专栏文章
题解:P11467 网瘾竞赛篇之 generals 大法好
P11467题解参与者 1已保存评论 0
文章操作
快速查看文章及其快照的属性,并进行相关操作。
- 当前评论
- 0 条
- 当前快照
- 1 份
- 快照标识符
- @mip5j18q
- 此快照首次捕获于
- 2025/12/03 06:30 3 个月前
- 此快照最后确认于
- 2025/12/03 06:30 3 个月前
非常好的贪心,使我的大脑旋转。
因为不论每个城堡的耗费兵力多少,它们每回合对总兵力的贡献都是 ,所以我们肯定要按兵力从小到大攻占城堡。
其次,如果在某一回合我们的总兵力已经可以攻占某一座城堡,那么立刻攻占该城堡一定优于在若干回合后再攻占该城堡,因为城堡消耗兵力不变,越早攻占,这座城堡就会提供越多的贡献。
那么就很好写了,我们预处理出 和 两个数组, 表示最早在第几回合可以攻下 座城堡, 表示攻下之后还剩多少兵力,然后对于每种情况进行模拟即可。
注意两个特判:
- 如果攻占了所有城堡仍不能超过对手,就是 。
- 如果一个城堡都不用攻占,即 ,就只用 回合。
CPP
#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;
}
}
相关推荐
评论
共 0 条评论,欢迎与作者交流。
正在加载评论...