Codeforces Round 961 (Div. 2)
1.Codeforces Round 958 (Div. 2)2.Codeforces Round 957 (Div. 3)3.Codeforces Round 959 sponsored by NEAR (Div. 1 + Div. 2)4.Codeforces Round 960 (Div. 2)5.AtCoder Beginner Contest 363
6.Codeforces Round 961 (Div. 2)
7.AtCoder Beginner Contest 3628.Codeforces Round 962 (Div. 3)9.Pinely Round 4 (Div. 1 + Div. 2)10.Educational Codeforces Round 168 (Rated for Div. 2)11.AtCoder Beginner Contest 36712.Codeforces Round 967 (Div. 2)13.Codeforces Round 968 (Div. 2)14.Educational Codeforces Round 173 (Rated for Div. 2)15.Educational Codeforces Round 172 (Rated for Div. 2)(C-D)16.Codeforces Round 998 (Div. 3)17.2025牛客寒假算法基础集训营218.2025牛客寒假算法基础集训营1题目链接:Codeforces Round 961 (Div. 2)
总结:B1wa两发可惜,C出得有点小慢。
A. Diagonals
fag:贪心
Description:给定一个
Solution:求最少占用,显然贪心处理,从最长的对角线开始占用,对角线长度为
void solve(){ cin >> n >> k; int res = 0; if (k == 0){ cout << 0 << endl; } else{ if (k <= n) cout << 1 << endl; else{ res = 1; k -= n; for (int i = n - 1; i; i --){ k -= i; res ++; if (k <= 0){ cout << res << endl; return; } k -= i; res ++; if (k <= 0){ cout << res << endl; return; } } } } }
B1. Bouquet (Easy Version)
fag: 模拟
Description:有
Solution:easy版,解法很多。这里使用前缀和+二分。
- 先按花瓣数从小到大排序。然后开始枚举,二分找到当前花瓣 + 1的最大下标
;花费不超过 的最大下标 ,取 。
Competing:第一发细节错误;第二发没考虑到花费不超过
void solve(){ cin >> n >> k; vector<int> a(n + 1); vector<int> s(n + 1); for (int i = 1; i <= n; i ++){ cin >> a[i]; } sort(a.begin(), a.end()); for (int i = 1; i <= n; i ++){ s[i] = s[i - 1] + a[i]; } int res = 0; for (int i = 1; i <= n; i ++){ if (a[i] > k) continue; int t = upper_bound(a.begin() + 1, a.end(), a[i] + 1) - a.begin(); int tt = upper_bound(s.begin() + 1, s.end(), s[i - 1] + k) - s.begin(); if (tt <= t){ res = max(res, s[tt - 1] - s[i - 1]); } else{ res = max(res, s[t - 1] - s[i - 1]); } } cout << min(k, res) << endl; }
B2. Bouquet (Hard Version)
fag:思维 + 贪心
Description:与easy的区别为,每种花有
Solution:考虑使用花瓣数为
Competing:应该是能想到的吧,毕竟只能买两种花
void solve(){ cin >> n >> k; vector<pii> a(n); for (int i = 0; i < n; i ++) cin >> a[i].fi; for (int i = 0; i < n; i ++) cin >> a[i].se; sort(a.begin(), a.end()); int ans = 0; for (int i = 0; i < n; i ++){ // 尽可能买第一种花 int t = k / a[i].fi; t = min(t, a[i].se); ans = max(ans, t * a[i].fi); if (a[i].fi + 1 != a[i + 1].fi || i + 1 == n) continue; // 剩下的买第二种花 int res = k - t * a[i].fi; int tt = res / a[i + 1].fi; tt = min(tt, a[i + 1].se); res = res - tt * a[i + 1].fi; ans = max(ans, k - res); if (t == 0) continue; // 还剩多少 tt = a[i + 1].se - tt; ans = max(ans, k - res + max(0LL, min({res, tt, t}))); if (ans == k){ cout << ans << endl; return; } } cout << ans << endl; }
C. Squaring
fag:分析
Description:给定一个数组,可以执行任意次操作,每次操作将每个数变为它的平方,求该数组变为不递减数组的最小操作次数。
Solution:显然,我们直接从前往后操作即可,但是直接平方会导致数很大,从而爆longlong。
- 那我们试试记录前面的数执行了多少次操作,根据开始两数之前的关系能否得出该数应该执行的操作次数。
- 对两个数取对数,
,我们发现两个数的操作次数 只与最开始的值有关。 - 我们开始预处理:如果
,我们令 为 的操作次数;如果 ,令 。如果 ,令 等于负的 大于等于 的操作次数,相当于可以少执行几次操作。但是我们要注意如果刚好可以令 ,那么 不变,否则 需要加 ,因为此时 了。
void solve(){ cin >> n; vector<int> a(n); vector<int> b(n); for (int i = 0; i < n; i ++){ cin >> a[i]; } int ans = 0; for (int i = 1; i < n; i ++){ if (a[i] < a[i - 1]){ if (a[i] == 1){ cout << -1 << endl; return; } else{ int t = a[i]; int c = 0; while (t < a[i - 1]){ t *= t; c ++; } b[i] = c; } } else if (a[i] == a[i - 1]){ b[i] = 0; } else{ int t = a[i - 1]; if (t == 1) continue; int c = 0; while (t < a[i]){ t *= t; c ++; } if (t == a[i]) b[i] = -c; else b[i] = -c + 1; } } for (int i = 1; i < n; i ++){ b[i] += b[i - 1]; if (b[i] < 0) b[i] = 0; ans += b[i]; } cout << max(ans, 0LL) << endl; }
合集:
题解
标签:
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框架的用法!