CF补题 993-Div.4
CF补题 993-Div.4-20241221
Dashboard - Codeforces Round 993 (Div. 4) - Codeforces
A:
题目大意:给出一个 \(n\) ,求有多少有序正整数数对 \((a,b)\),使得 \(a=n-b\)
#include <iostream> #define streampreset() ios::sync_with_stdio(false),cin.tie(0),cout.tie(0); using namespace std; int main() { streampreset(); int T; cin >> T; while (T--) { int n; cin >> n; cout << n - 1 << endl; } return 0; }
经典数学小知识
B:
题目大意:给出一个由 p,q,w
组成的字符串,求它的镜像串
#include <iostream> #include <string> #define streampreset() ios::sync_with_stdio(false),cin.tie(0),cout.tie(0); using namespace std; int main() { streampreset(); int T; cin >> T; while (T--) { string a; cin >> a; for (int i = a.size() - 1; i >= 0; i--) { if (a[i] == 'q') cout << 'p'; else if (a[i] == 'p') cout << 'q'; else cout << a[i]; } cout << endl; } return 0; }
正序输入,倒序输出,p,q
翻转 w
不变
C:
题目大意:\(2*m\) 个座位有 \(a+b+c\) 只猴子,\(a\) 猴子只能坐第一排, \(b\) 猴子只能坐第二排,\(c\) 猴子随便坐,求最大能坐下的猴子数
#include <iostream> #include <algorithm> #define streampreset() ios::sync_with_stdio(false),cin.tie(0),cout.tie(0); using namespace std; int main() { streampreset(); int T; cin >> T; while (T--) { int m, a, b, c; int ans = 0; cin >> m >> a >> b >> c; ans+=min(a,m); ans+=min(b,m); ans+=min(2*m-min(a,m)-min(b,m),c); cout<<ans<<endl; } return 0; }
贪心,首先安排 \(a,b\) 猴子,剩下的座位就是 \(c\) 猴的
D:
题目大意:给出一个序列a
,构造一个序列b
使得 \(a_i\) 是 \(1\le i \le n\) 上的 \([b_1,b_2...b_i]\) 的模,模指的是一个序列中出现次数最多的数(众数)
#include <iostream> #define streampreset() ios::sync_with_stdio(false),cin.tie(0),cout.tie(0); using namespace std; int a, st[200010]; int n; int main() { streampreset(); int T; cin >> T; while (T--) { memset(st, 0, sizeof st); cin >> n; int d = 1; for (int i = 1; i <= n; i++) { cin >> a; while (st[d]) d++;//定位 if (st[a]) { cout << d << ' ';//如果出现过,就填d st[d]++; } else { cout << a << ' ';没有出现过,就填a st[a]++; } } cout << endl; } return 0; }
脑筋急转弯,只要我们保证每次出现的数都不重复,即每个数都只出现一次,那么所有的数都是这个序列的模
所以我们维护一个状态序列,每次判断当前的 \(a_i\) 是否出现过,如果出现过,就使 \(b_i\) 为一个从未出现过的数,如果没有出现过,我们就把他加入序列
每次循环前,都要将d
定位到没有出现过的数上
E:
题目大意:对 \(x,y\) 两个正整数,给定两个区间 l1,r1,l2,r2
和一个底数 k
,求满足 \(\frac{y}{x}=k^n\) 的 \((x,y)\) 有序对数
#include <iostream> #include <algorithm> #include <math.h> #define streampreset() ios::sync_with_stdio(false),cin.tie(0),cout.tie(0); using namespace std; int main() { streampreset(); int T; cin >> T; while (T--) { long long k, la, ra, lb, rb; cin >> k >> la >> ra >> lb >> rb; long long sum = 1; long long ans = 0; long long u, v; while (sum <= rb) { long long i = la - 1, j = ra + 1; while (i + 1 != j) { long long mid = (i + j) >> 1; if (mid * sum >= lb) j = mid;// else i = mid; } u = j;//取分界右侧 i = la - 1, j = ra + 1; while (i + 1 != j) { long long mid = (i + j) >> 1; if (mid *sum > rb) j = mid; else i = mid; } v = i;//取分界左侧 if (u <= v) ans += v - u + 1; sum *= k; } cout << ans << endl; } return 0; }
\(\frac{y}{x}=k^n\) 可变形为 \(y=x*k^n\), \(x=\frac{y}{k^n}\) ,我们已知 \(x,y\) 的取值范围,通过枚举 \(n\) 再二分查找 \(x\) 的边界
枚举 \(n\) 只需要枚举到 \(k^n\le y_{max}\) ,因为超过界限后,左右边界都为 \(0\) 无意义
二分找 \(x\) 的边界,分别求满足 \(x*k^n=y_{min}\) 和 \(x*k^n=y_{max}\) 的\(x_u,x_v\)
最后答案加上 \(\sum_{u}^{v}(x)\) 即可,复杂度大约在 \(O(n\log n)\) 左右
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具