Codeforces Round #833 (Div. 2) A-D
A
题解
知识点:数学。
注意到 为奇数时,不考虑连续性,一共有 个格子,接下来证明一定能凑成方块。
从下往上从大到小摆,第 层摆 的矩形,第 层显然可以成对摆放 和 的矩形。
为偶数时,总数最多构成 大小的方形,和奇数情况一样,但会最后多一个最长的矩形。
时间复杂度
空间复杂度
代码
#include <bits/stdc++.h> #define ll long long using namespace std; bool solve() { int n; cin >> n; cout << (n + 1) / 2 << '\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> #define ll long long using namespace std; int a[100007]; bool solve() { int n; cin >> n; for (int i = 1;i <= n;i++) { char ch; cin >> ch; a[i] = ch - '0'; } ll ans = 0; for (int i = 1;i <= n;i++) { vector<int> cnt(10); int vis = 0, mx = 0; for (int j = i;j >= 1 && i - j + 1 <= 100;j--) { if (cnt[a[j]] == 0) vis++; cnt[a[j]]++; mx = max(mx, cnt[a[j]]); if (mx <= vis) ans++; } } 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> #define ll long long using namespace std; int a[200007]; ll sum[200007]; bool solve() { int n; cin >> n; for (int i = 1;i <= n;i++) cin >> a[i], sum[i] = sum[i - 1] + a[i]; int ans = 0, mx = 0; map<ll, int> mp; for (int i = n;i >= 1;i--) { mp[sum[i]]++; mx = max(mp[sum[i]], mx); if (a[i] == 0) { ans += mx; mx = 0; mp.clear(); } } ans += mp[0]; 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; }
D
题解
方法一
知识点:构造。
首先设 的尾 数为 ,如果 或 的尾 数小于 ,那么一定无解。因为 的因子包括 ,而 或 的因子或以后也不会包括 ,因为尾部有 。
如果有解,我们考虑用 把 和 同步,又要保证能被 整除。因此我们可以从第 位开始到第 位,如果 第 位为 则用 的第一个 通过加法填充这位 ,即 ,这只会影响第 位之后的位,之前的不会影响。
于是我们把 前 位同步,于是一定有 ,且或以后能被 整除 。
时间复杂度
空间复杂度
方法二
知识点:数论,构造。
方法一得到的结论是: 前 位除去 个尾 都用 加成 。设后 位为 于是 。
我们尝试直接求出这个 :
时间复杂度
空间复杂度
代码
方法一
#include <bits/stdc++.h> #define ll long long using namespace std; bool solve() { int a, b, d; cin >> a >> b >> d; int k = __builtin_ctz(d); if (k > __builtin_ctz(a) || k > __builtin_ctz(b)) return false; ll x = 0; for (int i = k;i < 30;i++) if (!(x & (1 << i))) x += (ll)d << (i - k); cout << x << '\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; }
方法二
#include <bits/stdc++.h> #define ll long long using namespace std; int qpow(int a, int k, int P) { int ans = 1; while (k) { if (k & 1) ans = 1LL * ans * a % P; k >>= 1; a = 1LL * a * a % P; } return ans; } bool solve() { int a, b, d; cin >> a >> b >> d; int k = __builtin_ctz(d); if (k > __builtin_ctz(a) || k > __builtin_ctz(b)) return false; d >>= k; ll x = (qpow((d + 1) / 2, 30 - k, d) - 1 + d) % d * (1LL << 30) + (1 << 30) - (1 << k); cout << x << '\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/16885937.html
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧