C++による基本プログラミング問題の解法

問題 1000: 2つの整数の合計

問題概要

2つの整数 ab を読み込み、それらの合計を出力してください。

C++ コード例

#include <iostream> // 標準入出力ライブラリをインクルード

int main() {
    int value1, value2; // 2つの整数値を格納する変数を宣言

    // 標準入力から2つの整数値を読み込む
    std::cin >> value1 >> value2;

    // 読み込んだ2つの数値の合計を計算し、標準出力に出力する
    std::cout << value1 + value2 << std::endl; // 計算結果の後に改行を追加

    return 0; // プログラムが正常終了したことを示す
}

問題 1001: EOFまでの2つの整数の合計

問題概要

入力が終了するまで(EOF: End-Of-File)、繰り返し2つの整数 ab を読み込み、それぞれの合計を出力してください。

C++ コード例

#include <iostream> // 標準入出力ライブラリをインクルード

int main() {
    int operandA, operandB; // 2つの整数値を格納する変数を宣言

    // std::cin の戻り値を利用して、入力が成功する限りループを続ける
    // 入力が失敗(例: EOFに到達、無効な入力)するとループは終了する
    while (std::cin >> operandA >> operandB) {
        // 読み込んだ2つの数値の合計を計算し、出力する
        std::cout << operandA + operandB << std::endl;
    }

    return 0; // プログラムが正常終了したことを示す
}

問題 1002: 1からNまでの合計

問題概要

整数 N を読み込み、1から N までの全ての整数の合計を計算して出力してください。

C++ コード例

#include <iostream> // 標準入出力ライブラリをインクルード

int main() {
    int upperLimit; // Nを格納する変数
    std::cin >> upperLimit; // Nを読み込む

    long long currentSum = 0; // 合計を格納する変数。Nが大きい場合にオーバーフローしないよう long long を使用。

    // 1から upperLimit までの数値をループで加算していく
    for (int i = 1; i <= upperLimit; ++i) {
        currentSum += i; // 合計に i を加える
    }

    // 計算された合計を出力する
    std::cout << currentSum << std::endl;

    return 0; // プログラムが正常終了したことを示す
}

問題 1003: 1からNまでの奇数の合計

問題概要

整数 N を読み込み、1から N までの全ての奇数の合計を計算して出力してください。

C++ コード例

#include <iostream> // 標準入出力ライブラリをインクルード

int main() {
    int limitValue; // Nを格納する変数
    std::cin >> limitValue; // Nを読み込む

    long long oddNumbersSum = 0; // 奇数の合計を格納する変数。オーバーフロー対策で long long。

    // 1から limitValue までの奇数のみをループで加算していく
    // i を 2 ずつ増やすことで奇数のみを処理する
    for (int i = 1; i <= limitValue; i += 2) {
        oddNumbersSum += i; // 合計に現在の奇数を加える
    }

    // 計算された奇数の合計を出力する
    std::cout << oddNumbersSum << std::endl;

    return 0; // プログラムが正常終了したことを示す
}

問題 1004: Nの階乗

問題概要

整数 N を読み込み、N の階乗 (N!) を計算して出力してください。

C++ コード例

#include <iostream> // 標準入出力ライブラリをインクルード

int main() {
    int numberForFactorial; // Nを格納する変数
    std::cin >> numberForFactorial; // Nを読み込む

    // 階乗の結果を格納する変数。Nが13以上になると int ではオーバーフローするため long long を使用。
    long long factorialResult = 1; 

    // 1から numberForFactorial までの数をループで掛け合わせて階乗を計算する
    for (int i = 1; i <= numberForFactorial; ++i) {
        factorialResult *= i; // factorialResult に i を掛ける
    }

    // 計算された階乗の結果を出力する
    std::cout << factorialResult << std::endl;

    return 0; // プログラムが正常終了したことを示す
}

問題 1005: 円の面積と円周

問題概要

円の半径 R を読み込み、その円の面積と円周を計算して、それぞれ小数点以下2桁まで表示してください。円周率には 3.1415926 を使用します。

C++ コード例

#include <iostream> // 標準入出力ライブラリ
#include <iomanip>  // 出力フォーマット設定のためのライブラリ

int main() {
    double radius; // 半径を格納する変数
    std::cin >> radius; // 半径を読み込む

    // 問題指定の円周率
    const double PI = 3.1415926; 

    // 円の面積を計算: 半径 * 半径 * 円周率
    double area = radius * radius * PI;
    // 円周を計算: 2 * 円周率 * 半径
    double circumference = 2 * PI * radius;

    // 出力の精度を小数点以下2桁に設定し、固定小数点表記を使用する
    std::cout << std::fixed << std::setprecision(2);

    // 面積と円周を出力する
    // 問題の出力形式に合わせて、面積の後に改行、その後に円周を出力
    std::cout << area << std::endl;
    std::cout << circumference << std::endl;

    return 0; // プログラムが正常終了したことを示す
}

問題 1006: アスタリスクによる三角形パターン

問題概要

整数 N を読み込み、N 行のアスタリスク (*) からなる中央揃えの三角形(ピラミッド)パターンを出力してください。

C++ コード例

#include <iostream> // 標準入出力ライブラリ

int main() {
    int numRows; // 行数を格納する変数
    std::cin >> numRows; // 行数を読み込む

    // 各行について処理
    for (int i = 1; i <= numRows; ++i) {
        // 先行スペースを出力: 各行の先頭には (numRows - i) 個のスペースが必要
        for (int j = 1; j <= numRows - i; ++j) {
            std::cout << " ";
        }

        // アスタリスクを出力: 各行には (2 * i - 1) 個のアスタリスクが必要
        for (int k = 1; k <= (2 * i - 1); ++k) {
            std::cout << "*";
        }
        
        // 各行の終わりに改行を出力
        std::cout << std::endl;
    }

    return 0; // プログラムが正常終了したことを示す
}

問題 1007: 大文字の文字数カウント

問題概要

ピリオド (.) で終わる文字列を読み込み、その中に含まれる大文字のアルファベットの数をカウントして出力してください。最大80文字まで処理します。

C++ コード例

#include <iostream> // 標準入出力ライブラリ
#include <cctype>   // isupper 関数を使用するためのライブラリ

int main() {
    char characterInput; // 1文字を格納する変数
    int uppercaseCount = 0; // 大文字の数をカウントする変数

    // 1文字ずつ読み込み、ピリオド '.' が現れるまで処理を続ける
    // (問題文には最大80文字とあるが、ここでは入力の長さのチェックは省略)
    while (std::cin >> characterInput) {
        if (characterInput == '.') {
            break; // ピリオドが現れたらループを終了
        }
        // 現在の文字が大文字のアルファベットであるかをチェック
        if (std::isupper(characterInput)) {
            uppercaseCount++; // 大文字であればカウントを増やす
        }
    }

    // カウントされた大文字の数を出力する
    std::cout << uppercaseCount << std::endl;

    return 0; // プログラムが正常終了したことを示す
}

問題 1008: 数字による三角形パターン

問題概要

整数 N を読み込み、N 行の数字からなる中央揃えの三角形パターンを出力してください。各行は行番号と同じ数字で構成されます。

C++ コード例

#include <iostream> // 標準入出力ライブラリ

int main() {
    int pyramidHeight; // ピラミッドの高さを格納する変数
    std::cin >> pyramidHeight; // 高さを読み込む

    // 各行について処理
    for (int row = 1; row <= pyramidHeight; ++row) {
        // 先行スペースを出力: 各行の先頭には (pyramidHeight - row) 個のスペースが必要
        for (int space = 1; space <= pyramidHeight - row; ++space) {
            std::cout << " ";
        }

        // 数字を出力: 各行には (2 * row - 1) 個の現在の行番号(row)が必要
        for (int digit = 1; digit <= (2 * row - 1); ++digit) {
            std::cout << row; // 現在の行番号を出力
        }
        
        // 各行の終わりに改行を出力
        std::cout << std::endl;
    }

    return 0; // プログラムが正常終了したことを示す
}

問題 1009: 配列の要素を逆順に出力

問題概要

まず整数 N を読み込み、次に N 個の整数を読み込んで配列に格納します。その後、配列の要素を逆順に(最後の要素から最初の要素まで)出力してください。

C++ コード例

#include <iostream> // 標準入出力ライブラリ
#include <vector>   // std::vector を使用するためのライブラリ

int main() {
    int elementCount; // 配列の要素数Nを格納する変数
    std::cin >> elementCount; // 要素数を読み込む

    // std::vector を使用して動的な配列を作成
    std::vector<int> numbers(elementCount);

    // N個の整数値を読み込み、ベクターに格納する
    for (int i = 0; i < elementCount; ++i) {
        std::cin >> numbers[i];
    }

    // ベクターの要素を逆順に出力する
    // 最後の要素から最初の要素までループし、各要素を出力
    for (int i = elementCount - 1; i >= 0; --i) {
        std::cout << numbers[i] << (i == 0 ? "" : " "); // 最後の要素の後にスペースを入れない
    }
    std::cout << std::endl; // 最後に出力全体を改行

    return 0; // プログラムが正常終了したことを示す
}

問題 1010: 挿入ソート

問題概要

まず整数 N を読み込み、次に N 個の整数を読み込んで配列に格納します。その配列を挿入ソートアルゴリズムを用いて昇順にソートし、ソート後の配列の要素をスペース区切りで出力してください。

C++ コード例

#include <iostream> // 標準入出力ライブラリ
#include <vector>   // std::vector を使用するためのライブラリ

int main() {
    int arraySize; // 配列のサイズNを格納する変数
    std::cin >> arraySize; // Nを読み込む

    // std::vector を使用して動的な配列を作成
    std::vector<int> dataElements(arraySize);

    // N個の整数値を読み込み、ベクターに格納する
    for (int i = 0; i < arraySize; ++i) {
        std::cin >> dataElements[i];
    }

    // 挿入ソートアルゴリズムの実装
    // 2番目の要素から開始し、前の要素と比較しながら適切な位置に挿入していく
    for (int i = 1; i < arraySize; ++i) {
        int keyElement = dataElements[i]; // 現在注目している要素
        int comparisonIndex = i - 1;       // 比較対象のインデックス

        // keyElement が比較対象の要素より小さい間、比較対象を1つ後ろにずらす
        while (comparisonIndex >= 0 && dataElements[comparisonIndex] > keyElement) {
            dataElements[comparisonIndex + 1] = dataElements[comparisonIndex];
            comparisonIndex--;
        }
        // keyElement を適切な位置に挿入
        dataElements[comparisonIndex + 1] = keyElement;
    }

    // ソートされた配列の要素を出力する
    for (int i = 0; i < arraySize; ++i) {
        std::cout << dataElements[i] << (i == arraySize - 1 ? "" : " "); // 最後の要素の後にスペースを入れない
    }
    std::cout << std::endl; // 最後に出力全体を改行

    return 0; // プログラムが正常終了したことを示す
}

問題 1011: ダイヤモンドパターン

問題概要

整数 N を読み込み、アスタリスク (*) とスペースからなる、高さが 2N-1 のダイヤモンドパターンを出力してください。

C++ コード例

#include <iostream> // 標準入出力ライブラリ

int main() {
    int diamondSize; // ダイヤモンドのサイズ(高さの中央値)Nを格納する変数
    std::cin >> diamondSize; // サイズを読み込む

    // ダイヤモンドの上半分(中央行を含む)の描画
    for (int i = 1; i <= diamondSize; ++i) {
        // 先行スペースを出力
        for (int j = 0; j < diamondSize - i; ++j) {
            std::cout << " ";
        }
        // アスタリスクを出力
        for (int j = 0; j < 2 * i - 1; ++j) {
            std::cout << "*";
        }
        std::cout << std::endl;
    }

    // ダイヤモンドの下半分の描画(中央行を除く)
    for (int i = diamondSize - 1; i >= 1; --i) {
        // 先行スペースを出力
        for (int j = 0; j < diamondSize - i; ++j) {
            std::cout << " ";
        }
        // アスタリスクを出力
        for (int j = 0; j < 2 * i - 1; ++j) {
            std::cout << "*";
        }
        std::cout << std::endl;
    }

    return 0; // プログラムが正常終了したことを示す
}

問題 1012: 文中の単語検索と位置特定

問題概要

ピリオド (.) で終了する文と、検索対象の単語が与えられます。文中でその単語が最初に出現する1から始まる位置(何番目の単語か)を出力してください。もし単語が見つからなかった場合は、文の長さから1を引いた値を出力してください(この要件は通常とは異なりますが、元のコードの挙動に合わせます)。

C++ コード例

#include <iostream> // 標準入出力ライブラリ
#include <string>   // std::string を使用するためのライブラリ

int main() {
    std::string sentenceInput;
    std::string searchTargetWord;
    int foundWordPosition = 0; // 検索単語が見つかった場合の1ベースのインデックス

    // ドット '.' を区切り文字として文全体を読み込む
    // この時点で sentenceInput にはドット自体は含まれない
    std::getline(std::cin, sentenceInput, '.');
    // 検索する単語を読み込む
    std::cin >> searchTargetWord;

    int currentWordCount = 0; // 現在処理中の単語の1ベースのカウント
    size_t sentenceLength = sentenceInput.length();
    size_t currentScanPos = 0; // 文をスキャンする現在の位置

    // 文の長さを超えるまでループ
    while (currentScanPos < sentenceLength) {
        // 単語の前のスペースをスキップ
        while (currentScanPos < sentenceLength && sentenceInput[currentScanPos] == ' ') {
            currentScanPos++;
        }
        if (currentScanPos == sentenceLength) { // スペースをスキップして文の終わりに達した場合
            break;
        }

        size_t wordStartPosition = currentScanPos; // 現在の単語の開始位置
        // 単語の終わりを見つける (次のスペースまたは文の終端まで)
        while (currentScanPos < sentenceLength && sentenceInput[currentScanPos] != ' ') {
            currentScanPos++;
        }
        size_t wordEndPosition = currentScanPos; // 現在の単語の終了位置の次

        // 抽出した単語
        std::string extractedWord = sentenceInput.substr(wordStartPosition, wordEndPosition - wordStartPosition);
        currentWordCount++; // 単語カウントを増やす

        // 抽出した単語が検索対象と一致するかチェック
        if (extractedWord == searchTargetWord) {
            foundWordPosition = currentWordCount; // 見つかった場合は位置を記録
            break; // ループを終了
        }
    }

    // 結果の出力
    if (foundWordPosition != 0) {
        std::cout << foundWordPosition << std::endl; // 単語が見つかった場合
    } else {
        // 単語が見つからなかった場合の特殊な要件
        // 通常は0や-1を出力することが多いが、元のコードの挙動に従う
        // sentenceInputが空の場合、length() - 1 は -1 になるため0を返す
        if (sentenceLength > 0) {
             std::cout << sentenceLength - 1 << std::endl;
        } else {
            std::cout << 0 << std::endl;
        }
    }

    return 0; // プログラムが正常終了したことを示す
}

問題 1013: 数値パズル

問題概要

ある6桁の整数 i (100007から999997の範囲) が存在し、その数から1桁目を削除し、代わりに先頭に7を付け加えた新しい数が、元の数 i の4倍になるものを見つけてください。この条件を満たす最初の i を出力してください。

C++ コード例

#include <iostream> // 標準入出力ライブラリ

int main() {
    // 100007から999997までの6桁の整数を探索
    for (int originalNumber = 100007; originalNumber <= 999997; ++originalNumber) {
        // originalNumber の1桁目を削除 (originalNumber を10で割る)
        int numberWithoutLastDigit = originalNumber / 10;
        
        // その先頭に7を付け加える (7 * 10^5 + numberWithoutLastDigit)
        // 700000 は 7 * 10^5
        long long transformedNumber = 700000LL + numberWithoutLastDigit; // long long を使用してオーバーフローを防ぐ

        // transformedNumber が originalNumber の4倍であるかチェック
        // かつ、割り切れることを確認 (transformedNumber % originalNumber == 0)
        if (transformedNumber / originalNumber == 4 && transformedNumber % originalNumber == 0) {
            std::cout << originalNumber << std::endl; // 条件を満たす最初の数を出力
            return 0; // プログラムを終了
        }
    }
    
    return 0; // プログラムが正常終了したことを示す
}

問題 1014: 調和級数の部分和

問題概要

整数 N を読み込み、調和級数の最初の N 項、つまり 1/1 + 1/2 + ... + 1/N の合計を計算して、小数点以下3桁まで出力してください。

C++ コード例

#include <iostream> // 標準入出力ライブラリ
#include <iomanip>  // 出力フォーマット設定のためのライブラリ

int main() {
    int termsCount; // Nを格納する変数
    std::cin >> termsCount; // Nを読み込む

    double harmonicSum = 0.0; // 調和級数の合計を格納する変数

    // 1から termsCount までの各整数 i について 1.0/i を合計に加える
    for (int i = 1; i <= termsCount; ++i) {
        harmonicSum += 1.0 / i; // i が int の場合でも浮動小数点除算を行うために 1.0 を使用
    }

    // 出力の精度を小数点以下3桁に設定し、固定小数点表記を使用する
    std::cout << std::fixed << std::setprecision(3);

    // 計算された合計を出力する
    std::cout << harmonicSum << std::endl;

    return 0; // プログラムが正常終了したことを示す
}

問題 1015: 鶏と兎の問題

問題概要

合計50匹の鶏と兎がいます。鶏はそれぞれ2本足、兎はそれぞれ4本足です。足の総数が160本であるとき、鶏と兎はそれぞれ何匹いるか計算して出力してください。

C++ コード例

#include <iostream> // 標準入出力ライブラリ

int main() {
    // 鶏の数を0から50まで試行 (最大50匹全て鶏の場合)
    for (int numChickens = 0; numChickens <= 50; ++numChickens) {
        // 兎の数を0から50まで試行 (最大50匹全て兎の場合)
        for (int numRabbits = 0; numRabbits <= 50; ++numRabbits) {
            // 足の総数の方程式: 鶏の足 (2 * numChickens) + 兎の足 (4 * numRabbits) == 160
            // 生き物の総数の方程式: 鶏の数 + 兎の数 == 50
            // (注: 元の問題文は鶏4本、兎2本だったが、典型的な鶏兎問題の足を修正して対応)
            if ((numChickens * 2 + numRabbits * 4 == 160) && (numChickens + numRabbits == 50)) {
                // 条件を満たす組み合わせが見つかったら出力
                // 元の問題の出力順序に合わせて兎の数、鶏の数を出力
                std::cout << numRabbits << " " << numChickens << std::endl;
                return 0; // 一意な解が期待されるため、見つけたら終了
            }
        }
    }

    return 0; // プログラムが正常終了したことを示す
}

問題 1016: 硬貨の組み合わせ

問題概要

合計金額 X と、2種類の硬貨の額面 AB が与えられます。それぞれの硬貨を少なくとも1枚使用して、合計金額 X を作る組み合わせが何通りあるかをカウントして出力してください。

C++ コード例

#include <iostream> // 標準入出力ライブラリ

int main() {
    int targetAmount;   // 目標金額X
    int coinValueA;     // 硬貨Aの額面
    int coinValueB;     // 硬貨Bの額面
    std::cin >> targetAmount >> coinValueA >> coinValueB;

    int validCombinationsCount = 0; // 条件を満たす組み合わせの数

    // 硬貨Aの枚数を試行 (1枚以上使用するため 1 から開始)
    // 最大枚数は (targetAmount / coinValueA) まで
    for (int countA = 1; countA * coinValueA <= targetAmount; ++countA) {
        // 硬貨Bの枚数を試行 (1枚以上使用するため 1 から開始)
        // 最大枚数は (targetAmount / coinValueB) まで
        for (int countB = 1; countB * coinValueB <= targetAmount; ++countB) {
            // 現在の組み合わせが目標金額Xと一致するかチェック
            if (countA * coinValueA + countB * coinValueB == targetAmount) {
                validCombinationsCount++; // 条件を満たす組み合わせであればカウントを増やす
            }
        }
    }

    // カウントされた組み合わせの数を出力する
    std::cout << validCombinationsCount << std::endl;

    return 0; // プログラムが正常終了したことを示す
}

問題 1017: 特定の剰余条件を満たす数

問題概要

100から199の範囲で、以下の3つの条件をすべて満たす最初の整数を見つけて出力してください:

  1. 3で割ると2余る (num % 3 == 2)
  2. 5で割ると3余る (num % 5 == 3)
  3. 7で割ると5余る (num % 7 == 5)

C++ コード例

#include <iostream> // 標準入出力ライブラリ

int main() {
    // 100から199までの整数をループで試行
    for (int number = 100; number <= 199; ++number) {
        // 3つの条件をすべて満たすかチェック
        if ((number % 3 == 2) && (number % 5 == 3) && (number % 7 == 5)) {
            std::cout << number << std::endl; // 条件を満たす最初の数を出力
            return 0; // プログラムを終了
        }
    }

    return 0; // プログラムが正常終了したことを示す
}

問題 1018: 三角形の種類の判定

問題概要

3つの辺の長さ a, b, c が与えられます。これらの辺で三角形が構成できるか、できる場合はその三角形が直角三角形、鈍角三角形、鋭角三角形のいずれであるかを判定して出力してください。

C++ コード例

#include <iostream> // 標準入出力ライブラリ

int main() {
    int sideA, sideB, sideC; // 3つの辺の長さを格納する変数
    std::cin >> sideA >> sideB >> sideC;

    // まず三角形の成立条件をチェック: 任意の2辺の和が残りの1辺より大きい
    if (sideA + sideB > sideC && 
        sideB + sideC > sideA && 
        sideC + sideA > sideB) 
    {
        // 辺の長さを二乗する (オーバーフロー防止のため long long にキャスト)
        long long sqA = static_cast<long long>(sideA) * sideA;
        long long sqB = static_cast<long long>(sideB) * sideB;
        long long sqC = static_cast<long long>(sideC) * sideC;

        // ピタゴラスの定理の応用により三角形の種類を判定
        // 最も長い辺の二乗と他の2辺の二乗の和を比較
        if (sqA + sqB == sqC || sqB + sqC == sqA || sqA + sqC == sqB) {
            std::cout << "zhijiao" << std::endl; // 直角三角形
        } else if (sqA + sqB < sqC || sqB + sqC < sqA || sqA + sqC < sqB) {
            std::cout << "dunjiao" << std::endl; // 鈍角三角形
        } else { // 上記のいずれにも当てはまらない場合は鋭角三角形
            std::cout << "ruijiao" << std::endl; // 鋭角三角形
        }
    } else {
        std::cout << "no" << std::endl; // 三角形を構成できない
    }

    return 0; // プログラムが正常終了したことを示す
}

問題 1019: 階乗の合計

問題概要

整数 N を読み込み、1! + 2! + ... + N! の合計を計算して出力してください。

C++ コード例

#include <iostream> // 標準入出力ライブラリ

int main() {
    int limitValueN; // Nを格納する変数
    std::cin >> limitValueN; // Nを読み込む

    long long currentFactorial = 1; // 現在の階乗の値を保持する変数 (long long でオーバーフロー対策)
    long long totalFactorialSum = 0; // 階乗の合計を保持する変数 (long long でオーバーフロー対策)

    // 1から limitValueN までの各 i について、i! を計算し、それを合計に加える
    for (int i = 1; i <= limitValueN; ++i) {
        currentFactorial *= i; // i の階乗を計算 (i! = (i-1)! * i)
        totalFactorialSum += currentFactorial; // 計算された i! を合計に加える
    }

    // 計算された階乗の合計を出力する
    std::cout << totalFactorialSum << std::endl;

    return 0; // プログラムが正常終了したことを示す
}

問題 1020: 3桁の数と反転した数の合計

問題概要

3桁の整数 a を読み込み、その数と、その数を構成する桁を反転させた数(例: 123 -> 321)の合計を出力してください。

C++ コード例

#include <iostream> // 標準入出力ライブラリ

int main() {
    int originalNumber; // 3桁の整数を格納する変数
    std::cin >> originalNumber; // 整数を読み込む

    // 各桁を抽出して数を反転させる
    int hundredsDigit = originalNumber / 100;       // 百の位
    int tensDigit = (originalNumber / 10) % 10;     // 十の位
    int unitsDigit = originalNumber % 10;           // 一の位

    // 桁を反転させた新しい数を構築
    int reversedNumber = unitsDigit * 100 + tensDigit * 10 + hundredsDigit;

    // 元の数と反転した数の合計を出力する
    std::cout << originalNumber + reversedNumber << std::endl;

    return 0; // プログラムが正常終了したことを示す
}

問題 1021: 複数の剰余条件を満たす数(最大500まで)

問題概要

0から500の範囲で、以下の3つの条件をすべて満たす整数をすべて見つけて出力してください。各数値は改行して表示します:

  1. 3で割ると2余る (num % 3 == 2)
  2. 5で割ると3余る (num % 5 == 3)
  3. 7で割ると2余る (num % 7 == 2)

C++ コード例

#include <iostream> // 標準入出力ライブラリ

int main() {
    // 0から500までの整数をループで試行
    for (int number = 0; number <= 500; ++number) {
        // 3つの条件をすべて満たすかチェック
        if ((number % 3 == 2) && (number % 5 == 3) && (number % 7 == 2)) {
            std::cout << number << std::endl; // 条件を満たす数を出力
        }
    }

    return 0; // プログラムが正常終了したことを示す
}

問題 1022: 百銭買百鶏(百鶏問題)

問題概要

大鶏(雄鶏)1羽5元、中鶏(雌鶏)1羽3元、小鶏(ひよこ)3羽1元です。合計100元で合計100羽の鶏を買うとき、大鶏、中鶏、小鶏はそれぞれ何羽買えるか、全ての組み合わせを出力してください。ただし、各大鶏、中鶏、小鶏はそれぞれ少なくとも1羽は買うものとします。

C++ コード例

#include <iostream> // 標準入出力ライブラリ

int main() {
    // 大鶏 (roosters) の数を試行: 少なくとも1羽。最大で19羽 (20羽だと5*20=100元で他の鶏が買えない)。
    for (int numRoosters = 1; numRoosters <= 19; ++numRoosters) {
        // 中鶏 (hens) の数を試行: 少なくとも1羽。残りの予算と羽数で買える範囲。
        // 最大で (100 - numRoosters * 5 - 1(for chicks)) / 3
        for (int numHens = 1; numHens <= (100 - numRoosters * 5 - 1) / 3; ++numHens) {
            // 小鶏 (chicks) の数を計算: 合計100羽から大鶏と中鶏の数を引く
            int numChicks = 100 - numRoosters - numHens;

            // 小鶏の数が少なくとも1羽であり、かつ3の倍数であるかをチェック
            // 小鶏3羽で1元なので、小鶏の数は3の倍数でなければならない
            if (numChicks >= 1 && numChicks % 3 == 0) {
                // 総金額を計算
                int totalCost = (numRoosters * 5) + (numHens * 3) + (numChicks / 3);

                // 総金額が100元であるかチェック
                if (totalCost == 100) {
                    // 条件を満たす組み合わせを出力
                    std::cout << numRoosters << " " << numHens << " " << numChicks << std::endl;
                }
            }
        }
    }

    return 0; // プログラムが正常終了したことを示す
}

問題 1023: 素数判定

問題概要

整数 N を読み込み、それが素数であるか否かを判定してください。素数であれば 'T' を、そうでなければ 'F' を出力してください。

C++ コード例

#include <iostream> // 標準入出力ライブラリ
#include <cmath>    // sqrt 関数を使用するためのライブラリ

int main() {
    int numberToCheck; // 判定する整数Nを格納する変数
    std::cin >> numberToCheck; // Nを読み込む

    bool isPrime = true; // 素数であるか否かを示すフラグ。初期値は true。

    // 1は素数ではない
    if (numberToCheck == 1) {
        isPrime = false;
    } 
    // 2は唯一の偶数の素数
    else if (numberToCheck == 2) {
        isPrime = true; 
    }
    // 2より大きい偶数は素数ではない
    else if (numberToCheck % 2 == 0) {
        isPrime = false;
    }
    // 3以上の奇数について素数判定を行う
    else {
        // 3から numberToCheck の平方根までの奇数で割り切れるかチェック
        // divisor を2ずつ増やすことで奇数のみを効率的にチェックする
        for (int divisor = 3; divisor * divisor <= numberToCheck; divisor += 2) {
            if (numberToCheck % divisor == 0) {
                isPrime = false; // 割り切れたら素数ではない
                break;           // 1つでも約数が見つかれば判定は終了
            }
        }
    }

    // 判定結果に応じて 'T' または 'F' を出力
    if (isPrime) {
        std::cout << 'T' << std::endl;
    } else {
        std::cout << 'F' << std::endl;
    }

    return 0; // プログラムが正常終了したことを示す
}

問題 1024: 予算と数量の制約を持つ商品の購入

問題概要

合計金額 N 元が与えられます(例: N=10.0の場合、10.0元)。商品は3種類あります: ボールペンは8元、鉛筆は2元、鉛筆の芯は1元です。合計金額 N 元をちょうど使い切り、かつ購入した商品の総数が30本を超えるような組み合わせが何通りあるかを計算して出力してください。各商品は少なくとも1本購入する必要があります。

C++ コード例

#include <iostream> // 標準入出力ライブラリ

int main() {
    double budgetYuan; // 入力は浮動小数点数(元)
    std::cin >> budgetYuan;

    // 整数計算のために、予算を1元単位に変換。
    // 問題文の例(N*10)に従い、入力Nを10倍して整数で扱う(例: 10.0元 -> 100単位)。
    int totalBudgetUnits = static_cast<int>(budgetYuan * 10); 

    int combinationsCount = 0; // 条件を満たす組み合わせの数

    // ボールペン (8単位) の数を試行: 少なくとも1本から、予算内で買える最大数まで
    for (int pens = 1; pens * 8 <= totalBudgetUnits; ++pens) {
        // 鉛筆 (2単位) の数を試行: 少なくとも1本から、残りの予算で買える最大数まで
        for (int pencils = 1; pencils * 2 <= (totalBudgetUnits - pens * 8); ++pencils) {
            // 鉛筆の芯 (1単位) の数を計算
            // 残りの予算を鉛筆の芯でちょうど埋める
            int costPensPencils = pens * 8 + pencils * 2;
            int remainingBudget = totalBudgetUnits - costPensPencils;
            
            // 鉛筆の芯も少なくとも1本必要
            if (remainingBudget >= 1) { 
                int refills = remainingBudget; // 芯の値段は1単位なので、残りの予算がそのまま芯の数

                // 合計購入数が30本を超えるかチェック
                if (pens + pencils + refills > 30) {
                    combinationsCount++;
                }
            }
        }
    }

    // カウントされた組み合わせの数を出力
    std::cout << combinationsCount << std::endl;

    return 0; // プログラムが正常終了したことを示す
}

問題 1025: 硬貨の組み合わせ(合計100)

問題概要

1元、2元、5元の3種類の硬貨があります。これらの硬貨を組み合わせて合計100元を作る方法は何通りあるでしょうか。ただし、それぞれの硬貨は少なくとも1枚使用するものとします。

C++ コード例

#include <iostream> // 標準入出力ライブラリ

int main() {
    int totalCombinations = 0; // 条件を満たす組み合わせの数

    // 5元硬貨の枚数を試行 (少なくとも1枚使用するため 1 から開始)
    // 最大枚数は (100 / 5) = 20枚
    for (int count5 = 1; count5 * 5 <= 100; ++count5) {
        // 2元硬貨の枚数を試行 (少なくとも1枚使用するため 1 から開始)
        // 残りの金額 (100 - count5 * 5) から買える最大数
        for (int count2 = 1; count2 * 2 <= (100 - count5 * 5); ++count2) {
            // 1元硬貨の枚数を計算
            // 残りの金額を1元硬貨でちょうど埋める
            int remainingAmount = 100 - (count5 * 5 + count2 * 2);
            
            // 1元硬貨も少なくとも1枚使用するという条件と、残りの金額が0以上であることをチェック
            if (remainingAmount >= 1) { // 1元硬貨は remainingAmount 枚必要
                totalCombinations++; // 条件を満たす組み合わせであればカウントを増やす
            }
        }
    }

    // カウントされた組み合わせの数を出力する
    std::cout << totalCombinations << std::endl;

    return 0; // プログラムが正常終了したことを示す
}

タグ: C++ 競技プログラミング アルゴリズム 数学 入出力

7月2日 17:38 投稿