A - Payment Editorial by TumoiYorozu


この解説は、C++ に入門したばかりの中高生レベルを想定して、考察の方法、コードの書き方の解説をします。

問題の考察

ひとまずプログラミングのことは忘れて、実際に具体的な例を考えてみよう。

  • 1,900円の買い物をした場合、2,000円を払い、お釣りは100円になる。
  • 1,800円の買い物をした場合、2,000円を払い、お釣りは200円になる。
  • 1,700円の買い物をした場合、2,000円を払い、お釣りは300円になる。
  • 2,700円の買い物をした場合、3,000円を払い、お釣りは300円になる。
  • 3,700円の買い物をした場合、4,000円を払い、お釣りは300円になる。
  • 4,700円の買い物をした場合、5,000円を払い、お釣りは300円になる。

問題文では 『必要最小限の枚数の 1000 円札で支払いを行うものとします。』 と書かれていたが、一旦無視して、\(N\) の最大値である 10,000円 で支払いをする場合を考えてみよう。そうすると

  • 1,900円の買い物をした場合、お釣りは 8,100円になる。
  • 1,800円の買い物をした場合、お釣りは 8,200円になる。
  • 1,700円の買い物をした場合、お釣りは 8,300円になる。
  • 2,700円の買い物をした場合、お釣りは 7,300円になる。
  • 3,700円の買い物をした場合、お釣りは 6,300円になる。
  • 4,700円の買い物をした場合、お釣りは 5,300円になる。

となる。 この時、お釣りの1000円札の分を無視、つまり下3ケタのみに注目すると、もとの問題でのお釣りと一致することが分かる。

ここまでで問題の解き方にピンと来たら、試してみよう! もっとヒントが欲しいときはここをクリックして開いてね

お釣りの 1000円札の分を無視すると良いことが分かった。

これは 1000 で割ったときの余りである。

C++ では $a$ を $b$ で割った時の余りは `%` 記号を使って `a%b` と書けば求めることが出来る。

実際のコード例

コード例 (実際の提出のリンクはこちら)

#include <bits/stdc++.h>
using namespace std;
int main(){
    // int 型の変数(箱)を作る
    int N;

    // cin で入力を受け取ることができる。「>>」で区切ること(<<ではない)
    cin >> N;

    // 求める答えは、10000円支払ったときの1000円札以外のぶん、つまり1000で割った余りである。
    int answer = (10000-N) % 1000;

    // cout を使うと答えを出力することが出来る。「<<」で区切ること(>>ではない)
    // endl で改行する。
    cout << answer << endl;
}

if文を使った別解

もしも 1000円以下の買い物をしたときは、お釣りは \(1000-N\) で表せられる。

同様に、もしも1001円以上、2000円以下の買い物をしたとき、お釣りは \(2000-N\) で表せられる。

\(N\) の範囲は最大10000なので、10個分の条件分岐を書くことで表現することが出来る。

解答コード
実際の提出のリンクはこちら

    #include <bits/stdc++.h>
    using namespace std;
    int main(){
        int N;
        cin >> N;
    
        if (N <= 1000) {
            cout << 1000 - N << endl;
        
        } else if (N <= 2000) {
            cout << 2000 - N << endl;
        
        } else if (N <= 3000) {
            cout << 3000 - N << endl;
        
        } else if (N <= 4000) {
            cout << 4000 - N << endl;
        
        } else if (N <= 5000) {
            cout << 5000 - N << endl;
        
        } else if (N <= 6000) {
            cout << 6000 - N << endl;
        
        } else if (N <= 7000) {
            cout << 7000 - N << endl;
        
        } else if (N <= 8000) {
            cout << 8000 - N << endl;
        
        } else if (N <= 9000) {
            cout << 9000 - N << endl;
        
        } else {
            cout << 10000 - N << endl;
        }
    }

例では『もしも1001円以上、2000円以下の買い物をしたとき』と解説したので、これを素直に条件式で表現すると2個目のifは if (N <= 2000) ではなく if (1001 <= N && N <= 2000) になりそうである。

実際これでも正解であるが、\(N\) が1000円以下のケースは 7行目にある1個目の if が実行され、10行目にある else から 36 行目までは実行されない。よって 1001 <= N という条件は書かなくても良い。

if 文10個でも書けると解説したが、競技プログラミングの練習としては最初に紹介した、1つの数式で表せられる解法でも AC できるように復習すべきだろう。

posted:
last update: