题解:P11467 网瘾竞赛篇之 generals 大法好
N1tr0us_Acid · · 题解
非常好的贪心,使我的大脑旋转。
\texttt{Solution}
因为不论每个城堡的耗费兵力多少,它们每回合对总兵力的贡献都是
其次,如果在某一回合我们的总兵力已经可以攻占某一座城堡,那么立刻攻占该城堡一定优于在若干回合后再攻占该城堡,因为城堡消耗兵力不变,越早攻占,这座城堡就会提供越多的贡献。
那么就很好写了,我们预处理出
注意两个特判:
- 如果攻占了所有城堡仍不能超过对手,就是
-1 。 - 如果一个城堡都不用攻占,即
x > y ,就只用1 回合。
\texttt{Code}
#include <bits/stdc++.h>
using namespace std;
#define int long long
int x, y, n;
const int N = 2e5 + 10, inf = 0x3f3f3f3f;
int tt;
int a[N], tim[N], les[N];
signed main(void) {
cin >> tt;
while (tt --) {
cin >> n >> x >> y;
for (int i = 1; i <= n; i ++) cin >> a[i];
sort(a + 1, a + n + 1); // 一定要记得排序!
if(x + n <= y) { // 特判1
puts("-1");
continue;
}
if(x > y) { // 特判2
puts("1");
continue;
}
int nowx = 0, kx = x;
for (int i = 1; i <= n; i ++) {
if(a[i] <= nowx) {
tim[i] = tim[i - 1] + 1;
nowx -= a[i];
nowx += kx;
les[i] = nowx;
kx ++;
continue;
}
int del = (a[i] - nowx) / kx + ((a[i] - nowx) % kx != 0);
nowx += del * kx + kx;
nowx -= a[i];
kx ++;
tim[i] = tim[i - 1] + del + 1;
les[i] = nowx;
}
int ans = inf;
for (int i = y - x + 1; i <= n; i ++) { // 只有当 x + i > y 时,才有可能超过对手,所以 i 从 y - x + 1 开始。
int nowy = y * tim[i];
int del = nowy - les[i];
int wil = del / (x + i - y) + 1;
ans = min(ans, tim[i] + wil);
}
cout << ans << endl;
}
}