20240913 随机训练
GYM 105293 C
题目描述
有
你可以进行以下操作:
- 选择一个正整数
。 - 找到第一个
的 ,并令 。 - 如果该次操作没有影响到任何怪物,或有怪物死亡,则游戏结束。
求在在游戏结束前能做的最多操作。
思路
我们考虑尽量让前面的怪物血量降至
在打后面的怪物时,为了不打中前面的,所以必须保证
假设现在最少能打
时空复杂度均为
代码
#include<bits/stdc++.h>
using namespace std;
using ll = long long;
const int MAXN = 300001;
int t, n, a[MAXN], Max = 1;
ll ans;
void Solve() {
cin >> n;
ans = 0, Max = 1;
for(int i = 1; i <= n; ++i) {
cin >> a[i];
}
for(int i = 1; i <= n; ++i) {
if(Max < a[i]) {
ans += (a[i] + Max - 1) / Max - 1, a[i] = 1;
}
Max = max(Max, a[i] + 1);
}
cout << ans + 1 << "\n";
}
int main() {
ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
for(cin >> t; t--; Solve()) {
}
return 0;
}
GYM 105293 D
题目描述
给定一个集合
- 选择两个
中的数 ,从 中删除他们,并插入 。
求是否能有一种方法使得最终
思路
我们先证明,假设我们已经把
- 首先我们令
减去 。 - 接着我们令
减去 。
这样最终的值为
又因为我们能凑出
如果满足上述条件,那么我们贪心地求
最后使用上述方法构造即可。
时空复杂度均为
代码
#include<bits/stdc++.h>
using namespace std;
using ll = long long;
int t, n;
ll m, sum;
vector<ll> a, b;
void Solve() {
cin >> n >> m;
if(1ll * (1 + n) * n / 2 % 2 != (m % 2 + 2) % 2 || m == 1ll * (1 + n) * n / 2 || m == -1ll * (1 + n) * n / 2) {
cout << "NO\n";
return;
}
cout << "YES\n";
sum = -1ll * (1 + n) * n / 2, a.clear(), b.clear();
for(int i = n; i >= 1; --i) {
if(sum + 2ll * i <= m) {
sum += 2 * i, a.emplace_back(i);
}else {
b.emplace_back(i);
}
}
for(int i = 1; i < int(a.size()); ++i) {
cout << b[0] << " " << a[i] << "\n";
b[0] -= a[i];
}
for(int i = 0; i < int(b.size()); ++i) {
cout << a[0] << " " << b[i] << "\n";
a[0] -= b[i];
}
}
int main() {
ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
for(cin >> t; t--; Solve()) {
}
return 0;
}
本文作者:yaosicheng124
本文链接:https://www.cnblogs.com/yaosicheng124/p/18432086
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步