Codeforces Round 905 - div.3(A B C D E F)
目录
Codeforces Round 905 (Div. 3)
div 3 都是思维题 qwq
A. Morning
模拟光标移动即可
void solve(){ string ss; cin >> ss; char ch = '1'; int ans = 0; for(auto c : ss){ if(c != ch){ int x = c, y = ch; if(c == '0') x = '9' + 1; if(ch == '0') y = '9' + 1; ans += abs(x - y); ch = c; } ++ ans; } cout << ans << '\n'; return ; }
B. Chemistry
先统计每种字符出现的次数,再统计字符出现次数为奇数的个数
void solve(){ int n, k; string ss; cin >> n >> k >> ss; vector<int> cnt(26, 0); for(auto c : ss){ ++ cnt[c - 'a']; } int shu[2] = {0, 0}; for(int i = 0; i < 26; ++ i) if(cnt[i]) ++ shu[cnt[i] % 2]; if(k >= shu[1] - 1) cout << "YES\n"; else cout << "NO\n"; return ; }
C. Raspberries
分类讨论
k = 2,3,5 时,只有给定的数变成其的倍数才行,记录改变所需最小值即
k = 4 需特判,k = 4 = 2 * 2,我们可以利用两个奇数 2 步实现,可以利用一奇一偶 1 步实现,也可以偶数但不是 4 的倍数 2 步实现,也可以奇数 1 三步实现
void solve(){ int n, ans = inf, k, a, shu[2] = {0, 0}; cin >> n >> k; for(int i = 0; i < n; ++ i){ cin >> a; ans = min(ans, (k - a % k) % k); ++ shu[a % 2]; } if(k == 4){ if(shu[1] >= 2){ int t = 2 - min(2, shu[0]); ans = min(ans, t); }else if(shu[1] == 1){ if(shu[0] > 1) ans = 0; else if(shu[0] == 1) ans = min(ans, 1); else ans = min(ans, 3); }else{ if(shu[0] >= 2) ans = 0; } } cout << ans << '\n'; return ; }
D. In Love
利用 multiset 存给定的线段 {l, r},用来找最大
当
void solve(){ int q, l, r; char ch; cin >> q; multiset<pii> x, y; while(q --){ cin >> ch >> l >> r; if(ch == '+'){ x.insert({l, r}); y.insert({r, l}); }else{ x.erase(x.find({l, r})); y.erase(y.find({r, l})); } if(x.size() && x.rbegin() ->first > y.begin()->first) cout << "YES\n"; else cout << "NO\n"; } return ; }
E. Look Back
由给出的数据范围可以知道,直接遍历求解显然会超数据范围,所以我们要尽量避免直接改变数值
对每一个下标的数,最终都可以表示为
- 如果
,那么 ,cnt 表示最小的 x 使得 ,且当相等时 cnt 应当减一,因为题目所求的为最小操作次数 - 如果
,那么 ,cnt 表示表示最小的 x 使得
所以另外开一个数组存
void solve(){ int n; cin >> n; vector<int> a(n), b(n + 1, 0); for(int i = 0; i < n; ++ i) cin >> a[i]; ll ans = 0; for(int i = 1; i < n; ++ i){ if(a[i] >= a[i - 1]){ int t = a[i - 1], cnt = 0; while(t < a[i]){ ++ cnt; t <<= 1; } if(t > a[i]) -- cnt; b[i] += max(0, b[i - 1] - cnt); }else{ int t = a[i], cnt = 0; while(a[i - 1] > t){ ++ cnt; t <<= 1; } b[i] += b[i - 1] + cnt; } ans += b[i]; } cout << ans << '\n'; return ; }
F. You Are So Beautiful
注意到,我们选择的子序列在原数组中出现一次,那么一定有
所以问题转化为找数的首次出现和末次出现,对于一个末次出现,对答案的贡献即为其位置前(包括当前位置)首次出现的数的个数
void solve(){ int n; cin >> n; vector<int> a(n); map<int, int> last;// 记录最后一个出现的位置 for(int i = 0; i < n; ++ i){ cin >> a[i]; last[a[i]] = i; } map<int, int> pre; ll ans = 0; int cnt = 0; for(int i = 0; i < n; ++ i){ if(pre[a[i]] == 0) ++ cnt; ++ pre[a[i]]; if(last[a[i]] == i) ans += cnt; } cout << ans << '\n'; return ; }
本文来自博客园,作者:Qiansui,转载请注明原文链接:https://www.cnblogs.com/Qiansui/p/17782112.html
分类:
oj - Codeforces
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!