Codeforces Round #808 (Div. 2)
传送门:https://codeforces.com/contest/1708
错过了,第二天vp的,只写出了AB就卡C了,竟然看不出是贪心555
A. Difference Operations
题意:给一个数组,由如下操作,问能不能使得 到 全为0
操作是选择一个i,使得 。
解:显然 是的倍数,才可能被剪成0,同理
那么意味着所有数字都得是的倍数,并且中间不可以被0隔断。
#include <bits/stdc++.h> signed main() { int t; std::cin >> t; while (t--) { int n; std::cin >> n; int a[110] = {0}; for (int i = 1; i <= n; i++) std::cin >> a[i]; int k = a[1]; bool f = 1; for (int i = 2; i <= n; i++) { if (k == 0 && a[i] != 0 || a[i] % k != 0) f = 0; if (a[i - 1] == 0 && a[i]) f = 0; } if (f) std::cout << "YES" << std::endl; else std::cout << "NO" << std::endl; } }
B. Difference of GCDs
题意:构造一个长度为n的数组,满足所有数字都在区间[l,r]内。
并且所有 的值互不相同。i
解法:因为 又要互不相同,那么就必须 也就是说 然后就在[l,r]里随便找个倍数就行了。找不到就输出NO
#include <bits/stdc++.h> #define int long long const int N = 1e5 + 10; int a[N]; signed main() { std::ios::sync_with_stdio(false); int t; std::cin >> t; while (t--) { int n, l, r; std::cin >> n >> l >> r; bool f = 1; for (int i = 1; i <= n; i++) { a[i] = 0; for (int j = (l - 1) / i * i + i; j <= r; j += i) { if (j >= a[i]) { a[i] = j; break; } } if (!a[i]) f = 0; } if (!f) { std::cout << "NO" << std::endl; continue; } else { std::cout << "YES" << std::endl; for (int i = 1; i <= n; i++) std::cout << a[i] << " \n"[i == n]; } } }
C. Doremy's IQ
题意:有n天,第i天有考试i,难度为 有起始智商q,当q<=0时她无法继续参加考试。
如果参加的考试那么q--。
问如何选择哪几天考试能考的次数最多。答案以01串输出。
思路:贪心地想,掉智商肯定是越迟掉越好,如果在i天选择了掉智商的考试,那么之后也要义无反顾地考下去。于是,我们可以直接二分从哪天开始掉智商并能考完后面的全部考试的。求出i最小的方案即可输出。
#include <bits/stdc++.h> #define int long long const int N = 1e5 + 10; int a[N]; int ans[N]; int n, q; std::vector<int> ve; bool check(int p) { int qq = q; for (int i = 1; i < p; i++) { if (a[i] > qq) { ans[i] = 0; } else { ans[i] = 1; } } for (int i = p; i <= n; i++) { ans[i] = 1; if (a[i] > qq) qq--; } return qq >= 0; } signed main() { std::ios::sync_with_stdio(false); int t; std::cin >> t; while (t--) { std::cin >> n >> q; for (int i = 1; i <= n; i++) { std::cin >> a[i]; } int l = 0, r = n; while (l < r) { int m = (l + r) >> 1; if (check(m)) { r = m; } else l = m + 1; } check(l); for (int i = 1; i <= n; i++) { std::cout << ans[i]; } std::cout << "\n"; } }
D. Difference Array
题意:给一个数组。让你把它变成它的差分数组,然后升序,继续变成差分数组...
直到最终只剩一个数字,输出这个数字。
思路:直接模拟肯定不行,但是发现,随着差分操作,一定会出现大量的0,而0和0的差分还是0,那么我们就可以直接把所有的0拿出来,每次操作减一,然后算上新生成的。其他过程就暴力模拟就好了。
#include <bits/stdc++.h> #define int long long const int N = 1e5 + 10; int a[N]; signed main() { std::ios::sync_with_stdio(false); int t; std::cin >> t; while (t--) { int n; std::cin >> n; std::vector<int> ve[2]; for (int i = 1; i <= n; i++) { std::cin >> a[i]; ve[0].push_back(a[i]); } int now = 0; int cost0 = 0; while (ve[now].size() >= 2) { std::sort(ve[now].begin(), ve[now].end()); ve[now ^ 1].clear(); if (cost0) { ve[now ^ 1].push_back(ve[now][0]); cost0--; } for (int i = 0; i < ve[now].size() - 1; i++) { int k = ve[now][i + 1] - ve[now][i]; if (k == 0) { cost0++; } else ve[now ^ 1].push_back(k); } now ^= 1; } if (ve[now].size() == 0) std::cout << 0 << "\n"; else if (ve[now].size() == 1) { std::cout << ve[now][0] << "\n"; } else if (cost0 >= 1) { std::sort(ve[now].begin(), ve[now].end()); int k1 = ve[now][0], k2 = ve[now][1] - ve[now][0]; std::cout << std::abs(k1 - k2) << "\n"; } else std::cout << std::abs(ve[now][0] - ve[now][1]) << "\n"; } }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具