Codeforces Round #885 (Div. 2) A-D
A
代码
#include <bits/stdc++.h> using namespace std; using ll = long long; bool solve() { int n, m, k; cin >> n >> m >> k; int x, y; cin >> x >> y; bool ok = 1; for (int i = 1;i <= k;i++) { int xx, yy; cin >> xx >> yy; ok &= abs(x - xx) + abs(y - yy) & 1; } if (ok) cout << "YES" << '\n'; else cout << "NO" << '\n'; return true; } int main() { std::ios::sync_with_stdio(0), cin.tie(0), cout.tie(0); int t = 1; cin >> t; while (t--) { if (!solve()) cout << -1 << '\n'; } return 0; }
B
代码
#include <bits/stdc++.h> using namespace std; using ll = long long; vector<int> c[200007]; bool solve() { int n, k; cin >> n >> k; for (int i = 1;i <= k;i++) c[i].clear(); for (int i = 1;i <= k;i++) c[i].push_back(0); for (int i = 1;i <= n;i++) { int x; cin >> x; c[x].push_back(i); } for (int i = 1;i <= k;i++) c[i].push_back(n + 1); int ans = n; for (int i = 1;i <= k;i++) { priority_queue<int> pq; for (int j = 1;j < c[i].size();j++) pq.push(c[i][j] - c[i][j - 1] - 1); int mx = pq.top(); if (mx) { pq.pop(); pq.push((mx - 1) / 2); pq.push(mx / 2); } ans = min(ans, pq.top()); } cout << ans << '\n'; return true; } int main() { std::ios::sync_with_stdio(0), cin.tie(0), cout.tie(0); int t = 1; cin >> t; while (t--) { if (!solve()) cout << -1 << '\n'; } return 0; }
C
题意
给定长为 的数组 ,每次操作使得 。
问是否可以通过若干次操作使得 。
题目
知识点:数论。
注意到,操作到最后一定能使得 ,并进入周期为 的循环,那么只要每个位置的数字进入循环的操作次数模 同余即可。
模拟操作显然是不行的。注意到 时,有 。因此,可以直接 ,这样不影响操作次数模 的结果。随后,执行操作一次继续上述操作。
时间复杂度
空间复杂度
代码
#include <bits/stdc++.h> using namespace std; using ll = long long; int a[100007], b[100007]; bool solve() { int n; cin >> n; for (int i = 1;i <= n;i++) cin >> a[i]; for (int i = 1;i <= n;i++) cin >> b[i]; int ok = -1; for (int i = 1;i <= n;i++) { if (a[i] == 0 && b[i] == 0) continue; int tmp = 0; while (a[i]) { if (b[i]) a[i] %= 2 * b[i]; swap(a[i], b[i]); b[i] = abs(a[i] - b[i]); (++tmp) %= 3; } if (ok == -1) ok = tmp; else if (ok != tmp) return false; } cout << "YES" << '\n'; return true; } int main() { std::ios::sync_with_stdio(0), cin.tie(0), cout.tie(0); int t = 1; cin >> t; while (t--) { if (!solve()) cout << "NO" << '\n'; } return 0; }
D
题意
初始时有奖金 ,接下来可以执行 次操作,每次操作以下的一种:
- 奖金 加上 的个位数字。
- 使用奖金 ,不会使得奖金减少,使用的奖金会累加。
问最多能使用多少奖金。
题目
知识点:数学,三分。
显然要尽可能将 变大,再开始使用。
模拟操作1显然复杂度不行,考虑找到 增加的循环节。
我们发现 时,至多操作 次就不需要继续操作了。因此,考虑取不操作的答案和操作 次的答案的最大值即可。
对于其他情况,至多操作 次就会进入 的循环,因此同样也记录不操作的答案和操作 次的答案的最大值,之后可以利用循环快速计算答案。
对于一开始的贪心结论,我们很容易想到凸函数三分求极值,但样例提示这不是一个凸函数。注意到,循环节长度只有 ,若我们枚举终点在循环节中的位置,那么剩下的就是以常数 增加,这显然是个凸函数,可以用三分。
进一步地,最后那个凸函数是个二次函数,也可以直接求抛物线对称轴得到最值。
时间复杂度
空间复杂度
代码
#include <bits/stdc++.h> using namespace std; using ll = long long; bool solve() { ll s, k; cin >> s >> k; ll ans = s * k; s += s % 10; k--; ans = max(ans, s * k); if (s % 10 == 0) { cout << ans << '\n'; return true; } auto check = [&](ll x) { return (s + x * 20) * (k - x * 4); }; for (int i = 0;i < 4 && k;i++, s += s % 10, k--) { ll l = 0, r = k / 4; while (l <= r) { ll mid1 = l + (r - l) / 3; ll mid2 = r - (r - l) / 3; if (check(mid1) <= check(mid2)) l = mid1 + 1; else r = mid2 - 1; } ans = max(ans, check(r)); } cout << ans << '\n'; return true; } int main() { std::ios::sync_with_stdio(0), cin.tie(0), cout.tie(0); int t = 1; cin >> t; while (t--) { if (!solve()) cout << -1 << '\n'; } return 0; }
本文来自博客园,作者:空白菌,转载请注明原文链接:https://www.cnblogs.com/BlankYang/p/17564425.html
分类:
CF
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧