https://atcoder.jp/contests/abc207/tasks/abc207_b
解説
https://atcoder.jp/contests/abc207/submissions/23803329
愚直にシミュレーションをしていって、目標が達成されれば即座に回数を答えれば答えになる。
ただ、目標が達成可能でない場合は無限に操作が行われてしまうので適当な所で打ち切って-1を出力する。
解法を聞くとそれほど難しくないのだが、これで本当にいいのか?という疑問が残る。
正直、雰囲気で自分は解いたところがあるが、回数をcntと置くと、数式で整理ができて、これでよさそうという結論になる。
数式
操作回数がcntとすると、
水色のボールは A + B * cnt
赤色のボールは C * cnt
となっていることになる。水色が赤色のD倍以下ということは、
A + B * cnt ≦ C * cnt
A ≦ C * cnt - B * cnt
A ≦ (C - B) * cnt
という感じになる。左辺は正なので、C - Bが負になれば条件は満たされない。
正として考えると、
A / (C - B) ≦ cnt
となるので、条件を満たす最小のcntはAが上限になることが分かる。
つまり、答えがある場合は、105回くらいやれば達成できるということが分かる。
シミュレーション
なので105回を上限に(自分は心配症なので念のため計算量が余裕で間に合う106で本番はやったけれど)シミュレーションすればいい。
int A, B, C, D; //--------------------------------------------------------------------------------------------------- int solve() { ll mizu = A; ll aka = 0; rep(cnt, 1, 1010101) { mizu += B; aka += C; if (mizu <= aka * D) return cnt; } return -1; } //--------------------------------------------------------------------------------------------------- void _main() { cin >> A >> B >> C >> D; cout << solve() << endl; }