Codeforces Round 1067 (Div. 2)
A. Suspension
void solve(){ int n, y, r; cin >> n >> y >> r; cout << min(r + y / 2, n) << endl; }
B. Split
通过map记录数组每个元素出现的次数,遍历map,分别统计出现奇数次的元素和出现偶数次的元素个数。接着分类讨论,众所周知,想让一个数拆分后得到尽可能多的奇数,当一个数为偶数时,它可以拆分为两个奇数相加,当为奇数时,可以拆分为奇数加偶数或者干脆不拆分。根据题目,我们将遍历后得到的奇数个数 cnt1 和偶数个数 cnt0,当 cnt1 为0时,讨论 cnt0,若 cnt0 和 n 的奇偶性相同,则为 2*cnt0,否则为 2*(cnt0-1),若偶数不为0,为cnt1+2*cnt0
void solve(){ int n; cin >> n; vector<int> a(2 * n + 1); map<int, int> mp; for(int i = 1; i <= 2 * n; ++i) { cin >> a[i]; mp[a[i]]++; } int cnt0 = 0, cnt1 = 0; for(auto& [f, s] : mp){ if(s % 2) cnt1++; else cnt0++; } if(cnt1 == 0){ if(cnt0 % 2 == n % 2){ cout << 2 * cnt0 << endl; return ; }else{ cout << 2 * (cnt0 - 1) << endl; } }else{ cout << cnt1 + 2 * cnt0 << endl; return ; } }
C. Annoying Game
由题可知,Alice要最大化数组a的值,而Bob则要最小化,Alice先手,且有两种操作,一种是加 bi 另一种是减 bi,我们这样想。每当Alice加上一个数 bi 时,轮到Bob时就减去这个数,使得数组 a 的大小保持不变。由此可以达到,当 k 为偶数轮时,Alice 的操作次数和 Bob 的操作次数相同,数组 a 的大小不变,到奇数轮时,最后一次是Alice 操作,想让 a 的数最大,就加上一个最大的 bi 就行。但题目所要的是区间上的值,不是整个数组 a 的值,那么通过 dp 操作,遍历每个元素,得到当取这个元素时,从左开始的最大值和右开始的最大值得到 L 与 R 的数组。那么当我们遍历数组时,每当遍历到 ai ,那么区间最大和就是 Li + Ri - ai。加上 bi 后,区间最大和就是 Li + Ri - ai + bi。
void solve(){ int n, k; cin >> n >> k; vector<int> a(n + 1), b(n + 1); for(int i = 1; i <= n; ++i) cin >> a[i]; for(int i = 1; i <= n; ++i) cin >> b[i]; vector<int> L(n + 1, 0), R(n + 1, 0); L[1] = a[1]; for(int i = 2; i <= n; ++i){ if(L[i - 1] > 0) L[i] = L[i - 1] + a[i]; else L[i] = a[i]; } R[n] = a[n]; for(int i = n - 1; i >= 1; --i){ if(R[i + 1] > 0) R[i] = R[i + 1] + a[i]; else R[i] = a[i]; } if(k % 2 == 0){ int maxx = M; for(int i = 1; i <= n; ++i){ if(L[i] + R[i] - a[i] > maxx) maxx = L[i] + R[i] - a[i]; } cout << maxx << endl; }else{ int maxx = M; for(int i = 1; i <= n; ++i){ if(L[i] + R[i] - a[i] + b[i] > maxx) maxx = L[i] + R[i] - a[i] + b[i]; } cout << maxx << endl; } }

浙公网安备 33010602011771号