けんちょんの競プロ精進記録

競プロの精進記録や小ネタを書いていきます

AtCoder ABC 243 A - Shampoo (6Q, 灰色, 100 点)

シミュレーションで解くか、数学的に解こう!

問題概要

シャンプーが  V mL 余っている。

F さん、M さん、T さんが順に  A, B, C mL ずつ使っていく。最初にシャンプーが足りなくなる人が誰になるかを求めよ。

解法 (1):シミュレーション

まずは、シャンプーがなくなるまで、シャンプーを実際に 3 人で使い回していくシミュレーションを実装してみよう。

注意したいのは、ある人がシャンプーを使った結果  V = 0 になる場合というのは、まだ「その人はシャンプーを使い切れた」という判定になることだ。この場合、その次の人が「シャンプーが足りない」と認識することになる。

コード

#include <bits/stdc++.h>
using namespace std;

int main() {
    int V, A, B, C;
    cin >> V >> A >> B >> C;
    
    while (true) {
        V -= A;
        if (V < 0) {
            cout << "F" << endl;
            return 0;
        }
        V -= B;
        if (V < 0) {
            cout << "M" << endl;
            return 0;
        }
        V -= C;
        if (V < 0) {
            cout << "T" << endl;
            return 0;
        }
    }
}

 

解法 (2):数学的に解く

3 人が 1 回ずつ使うと、シャンプーを  A + B + C ずつ消費することに注意しよう。そこで、 V A + B + C で割ってみよう。割ったときの商を  q、余りを  r とする。

このとき、3 人が  q 回ずつシャンプーを使って、 r mL だけ余った状態で、F さんの番になる。

  • もし、 r \lt A ならば、F さんがシャンプーが足りない
  • もし、 A \le r \lt A + B ならば、M さんがシャンプーが足りない
  • そうでなければ、T さんがシャンプーが足りない

と結論づけることができる。

コード

#include <bits/stdc++.h>
using namespace std;

int main() {
    int V, A, B, C;
    cin >> V >> A >> B >> C;
    
    int r = V % (A + B + C);
    if (r < A) cout << "F" << endl;
    else if (r < A + B) cout << "M" << endl;
    else cout << "T" << endl;
}