[GDKOI2024 普及组] 刷野 I 题解
i_was_wrong · · 题解
[GDKOI2024 普及组] 刷野 I 题解
感谢潘德理2010提供的hack。
选择使用贪心的思想,通过不断选择最优的攻击方式来最小化受到的血量伤害。
思路
一眼贪心:
-
当我们还有能量且怪兽剩余数量大于
2 ,那我们就用天雷破。 -
但我们还有能量且怪兽数量小于等于
2 ,若有怪兽血量等于1 ,使 用天雷破。如果没有,使用天音波。 -
没有能量了,用普通攻击。
证明
我们想要让每次怪物受到的总伤害最大。那么当怪物数量大于
代码
include <bits/stdc++.h>
using namespace std;
#define int long long
const int N = 1e5 + 5;
int n, m, a[N], ans, q; // 定义全局变量:怪物数量n,能量值m,怪物血量数组a,最终答案ans,额外伤害q
// 模拟游戏战斗的函数
void play() {
int x = a[n - 1], y = a[n];
while (x > 0 || y > 0) {
if (m > 0) {
m--;
if (x > 2)
x -= 2, ans += 2;
else if (x == 2)
x -= 2, ans++;
else if (x == 1 && y > 1)
x--, y--, ans++;
else if (x == 1 && y == 1)
x--, y--;
else if (y == 2)
y -= 2;
else
y -= 2, ans++;
} else {
if (x > 0) {
ans += 2 * (x - 1) + y;
x = 0, y = 0;
} else if (y > 0) {
ans += y - 1;
y = 0;
}
}
}
}
signed main() {
cin >> n >> m;
for (int i = 1; i <= n; i++)
cin >> a[i];
sort(a + 1, a + n + 1);
if(a[n]==1){cout<<0;return 0;}//注意,这里要特判,是否可以天音波直接带走
if (a[n - 2] <= m) {
// 特殊情况处理:攻击第n-2个怪物,然后进行普通攻击
m -= a[n - 2];
for (int i = 1; i <= n - 2; i++) ans += a[i] - 1;
ans += 2 * a[n - 2];
a[n - 1] -= a[n - 2], a[n] -= a[n - 2];
play();
} else {
// 一般情况处理:贪心算法计算受到的总伤害
for (int i = 1; i <= n; i++) {
ans += q;
ans += a[i] - 1;
if (a[i] >= m) q += a[i] - m;
}
}
cout << ans; // 输出最终答案
return 0;
}