公式

A - 証明書の交付 / Issuing Certificates 解説 by admin

gpt-6-astra-medium

概要

所持金 \(B\) 円で、1 枚あたり \(A\) 円の証明書を \(N\) 枚購入できるかを判定します。提示されたコードでは、1 枚ずつ手数料を支払う処理をシミュレーションしています。

考察

証明書を 1 枚受け取るたびに、所持金から \(A\) 円を支払います。そのため、支払う直前の残金について、次のように判断できます。

  • 残金が \(A\) 円未満なら、次の 1 枚の手数料を払えないので No。
  • 残金が \(A\) 円以上なら、\(A\) 円を引いて次の支払いへ進む。

これを \(N\) 回繰り返せれば、すべての手数料を払えるので Yes です。

例えば、\(N=3,\ A=200,\ B=500\) の場合、残金は \(500 \to 300 \to 100\) 円と変化します。3 枚目の支払いに必要な \(200\) 円が残っていないため、答えは No となります。

この問題では \(N \leq 100\) なので、1 枚ずつ支払う素朴な方法でも十分高速であり、TLE にはなりません。ただし、残金がちょうど \(A\) 円なら支払えるため、判定条件を「\(A\) 円以下」にすると誤答になります。

なお、手数料の合計は \(N \times A\) 円なので、\(N \times A \leq B\) を直接判定する方法でも解けます。

アルゴリズム

  1. \(N, A, B\) を読み込み、残金を表す変数 money に \(B\) を代入します。
  2. 次の処理を \(N\) 回繰り返します。
    • money が \(A\) 未満なら、No を出力して終了します。
    • そうでなければ、money から \(A\) を引きます。
  3. 途中で終了せずに \(N\) 回の支払いを終えたら、Yes を出力します。

各支払いの前に残金を確認しているため、支払えない場合は必ず No になります。また、最後まで処理が続いた場合は \(N\) 枚分を実際に支払えているため、Yes と判定できます。

計算量

  • 時間計算量: \(O(N)\)
    最大で \(N\) 回、支払いの判定と残金の更新を行います。
  • 空間計算量: \(O(1)\)
    残金やループ変数など、一定個数の変数だけを使用します。

実装のポイント

  • 支払い不能の条件は money < a です。money == a の場合は支払えます。

  • すべて支払った後の残金が \(0\) 円でも問題ありません。

  • No を出力したら、その場で return 0; により終了します。これにより、最後の Yes が余分に出力されることを防げます。

  • 出力は、大文字・小文字を含めて指定どおりの Yes または No にします。

    ソースコード

// 問題文から独立に実装: 1枚ずつ払っていき、途中で足りなくなったら No
#include <iostream>
int main() {
    int n, a, b; std::cin >> n >> a >> b;
    int money = b;
    for (int i = 0; i < n; ++i) {
        if (money < a) { std::cout << "No" << std::endl; return 0; }
        money -= a;
    }
    std::cout << "Yes" << std::endl;
}


この解説は gpt-6-astra-medium によって生成されました。