[ARC144] B - Gift Tax
[Q] https://atcoder.jp/contests/arc144/tasks/arc144_b
求めたい値で、にぶたんするだけ。
入力例2
N=3 a=2 b=3
A[]: 11 1 2
・ans=10 と仮定した場合、a操作とb操作の必要回数を求めていく。
A[0]-10 = 11-10 = +1なので、1/3 = 0回b操作できる。(できない)
A[1]-10 = 1-10 = -9なので、(9+(a-1))/a = 10/2 = 5回a操作が必要。
A[2]-10 = 2-10 = -8なので、(8+(a-1))/a = 8/2 = 4回a操作が必要。
b操作が0回、a操作が9回、は成立しないので、10は大きすぎ。
bが余る分には問題がないので、b操作>=a操作のとき、解答を満たす。
・ans=4 と仮定した場合、a操作とb操作の必要回数を求めていく。
A[0]-4 = 11-4 = +7なので、7/3 = 2回b操作できる。
A[1]-4 = 1-4 = -3なので、(3+(a-1))/a = 4/2 = 2回a操作が必要。
A[2]-4 = 2-4 = -2なので、(2+(a-1))/a = 3/2 = 1回a操作が必要。
Bcnt=2 < Acnt=3 なのでダメ。
・ans=3 と仮定した場合、a操作とb操作の必要回数を求めていく。
A[0]-3 = 11-3 = +8なので、8/3 = 2回b操作できる。
A[1]-3 = 1-3 = -2なので、(2+(a-1))/a = 3/2 = 1回a操作が必要。
A[2]-3 = 2-3 = -1なので、(1+(a-1))/a = 2/2 = 1回a操作が必要。
Bcnt=2 >= Acnt=2。Bcntに余裕があるケースなのでOK。
ans = 3
・実装
int main() {
ll N, a, b;
cin >> N >> a >> b;
ll A[N];
ll ans = 0;
rep(i, N) cin >> A[i];
// 二分探索
ll high = 1e9 + 10000;
ll low = 0;
while (high - low > 1) {
ll Acnt = 0;
ll Bcnt = 0;
ll mid = (high + low) / 2;
// 引く数と、タス数をだす
rep(i, N) {
ll dif = A[i] - mid;
if (dif > 0) { // 何回Bしていいか。余裕度
Bcnt += dif / b;
} else { // 何回Aする必要があるか。必要度
Acnt += (abs(dif) + a - 1) / a;
}
}
// Bが余る分にはかまわない
if (Bcnt >= Acnt) {
low = mid; // lowが解答になる
} else
high = mid;
}
cout << low << endl;
}
この記事が気に入ったらサポートをしてみませんか?