Codeforces Round #575 (Div. 3)
比赛链接:https://codeforces.com/contest/1196
A - Three Piles of Candies
题意
有 3 份糖果,Alice 先拿一份,Bob 后拿一份,最后 Alice 再拿一份,糖果较多的人要把多出来的分给另一个人,如果两个人都采取最优策略,Alice 最多能有多少个糖果。
题解
不管怎么取,Bob 一定可以拿到较少两份中的一份,也因此最多的一份一定是 Alice 的,所以 Alice 所拥有的糖果数一定比 Bob 多,答案即为 3 份平分后较少的一份。
代码
#include <bits/stdc++.h> using namespace std; void solve() { long long a, b, c; cin >> a >> b >> c; cout << (a + b + c) / 2 << "\n"; } int main() { int t; cin >> t; while (t--) solve(); }
B - Odd Sum Segments
题意
将大小为 n 的数组分为 k 个和为奇数的区间,输出每个区间的右端点。(区间两两不相交且合并后为原数组)
题解
有解的情况:
- 至少有 k 个奇数
- 多出来的奇数个数为偶数
之后一个奇数一个右端点地划分 k - 1 个区间,第 k 个区间的右端点为 n 即可。
代码
#include <bits/stdc++.h> using namespace std; void solve() { int n, k; cin >> n >> k; long long a[n + 1] = {}; int odd = 0; for (int i = 1; i <= n; i++) { cin >> a[i]; if (a[i] & 1) ++odd; } if (k > odd or (odd - k) % 2 != 0) { cout << "NO" << "\n"; return; } vector<int> ans; for (int i = 1; i <= n; i++) { if (a[i] & 1) ans.push_back(i); } ans.resize(k - 1); ans.push_back(n); cout << "YES" << "\n"; for (auto i : ans) cout << i << ' '; cout << "\n"; } int main() { int t; cin >> t; while (t--) solve(); }
C - Robot Breakout
题意
坐标系内有 n 个机器人,给出坐标及其能移动的方向(上下左右),找出一个所有机器人都能移动到的点。
题解
考虑到:
- 如果一个机器人不能向左移动,此时它的 x 坐标即为最小的 x 坐标
- 如果一个机器人不能向右移动,此时它的 x 坐标即为最大的 x 坐标
- 如果一个机器人不能向上移动,此时它的 y 坐标即为最大的 y 坐标
- 如果一个机器人不能向下移动,此时它的 y 坐标即为最小的 y 坐标
即记录最小最大的 x、y 坐标,答案即四者围成的矩形内的点。
代码
#include <bits/stdc++.h> using namespace std; const int INF = 1e5; void solve() { int n; cin >> n; int mix = -INF, mxx = INF; int miy = -INF, mxy = INF; for (int i = 0; i < n; i++) { int x, y, l, u, r, d; cin >> x >> y >> l >> u >> r >> d; if (!l) mix = max(mix, x); if (!u) mxy = min(mxy, y); if (!r) mxx = min(mxx, x); if (!d) miy = max(miy, y); } if (mix <= mxx and miy <= mxy) cout << 1 << ' ' << mix << ' ' << miy << "\n"; else cout << 0 << "\n"; } int main() { int t; cin >> t; while (t--) solve(); }
D2 - RGB Substring (hard version)
题意
有一个由 'R', 'G', 'B' 组成的字符串 s 和无限字符串 "RGBRGB...",问至少要改变 s 中的多少个元素才能得到无限字符串的一个长为 k 的连续子串。
题解
假设存在改变次数最少的长为 k 的连续子串,那么该连续子串一定是以 'R' 或 'G' 或 'B' 开头的,依次尝试将字符串 s 替换为以三者之一开头的无限字符串,记录替换次数最少的长为 k 的连续子串即可。
代码
#include <bits/stdc++.h> using namespace std; const string t = "RGB"; void solve() { int n, k; cin >> n >> k; string s; cin >> s; int ans = 1e9; for (int step = 0; step < 3; step++) { int res[n] = {}; int cur = 0; for (int i = 0; i < n; i++) { res[i] = s[i] != t[(i + step) % 3]; cur += res[i]; if (i >= k) cur -= res[i - k]; if (i >= k - 1) ans = min(ans, cur); } } cout << ans << "\n"; } int main() { int t; cin >> t; while (t--) solve(); }

浙公网安备 33010602011771号