比赛链接:https://codeforces.com/contest/1374
A. Required Remainder
题意
给出 $x, y, n$,找到最大的整数 $0 le k le n$,使得 $k mod x = y$ 。
题解
$k = mx + y$,求得满足条件最大的 $m$ 即可。
代码
#include <bits/stdc++.h> using namespace std; void solve() { int x, y, n; cin >> x >> y >> n; int m = n / x; cout << (m * x + y > n ? (m - 1) * x + y : m * x + y) << " "; } int main() { int t; cin >> t; while (t--) solve(); }
B. Multiply by 2, divide by 6
题意
给出一个整数 $n$,每次可以选择乘以 $2$ 或 除以 $6$(如果 $n$ 被 $6$ 整除的话),问 $n$ 最终能否变为 $1$ 以及最少的操作次数。
题解
如果 $n$ 有除 $2,3$ 外的素因子或 $cnt_2 > cnt_3$ 则无解,否则乘以 $cnt_3 - cnt_2$ 个 $2$ 再除以 $cnt_3$ 个 $6$ 即可。
代码
#include <bits/stdc++.h> using namespace std; void solve() { int n; cin >> n; int cnt_3 = 0, cnt_2 = 0; while (n % 3 == 0) n /= 3, ++cnt_3; while (n % 2 == 0) n /= 2, ++cnt_2; cout << (n != 1 or cnt_2 > cnt_3 ? -1 : (cnt_3 - cnt_2) + cnt_3) << " "; } int main() { int t; cin >> t; while (t--) solve(); }
C. Move Brackets
题意
给出一个长度为偶数 $n$ 的括号序列,序列含有 $frac{n}{2}$ 个左括号和右括号,每次操作可以把一个括号移至序列首部或尾部,问使得序列合法的最少操作次数。
题解
计算不能被闭合的右括号的个数即可。
代码
#include <bits/stdc++.h> using namespace std; void solve() { int n; cin >> n; string s; cin >> s; int l = 0, r = 0; for (char c : s) { if (c == '(') ++l; else if (l) --l; else ++r; } cout << r << " "; } int main() { int t; cin >> t; while (t--) solve(); }
D. Zero Remainder Array
题意
给出一个大小为 $n$ 的数组 $a$,初始时 $x = 0$,每次可以选择一种操作:
- $a_i := a_i + x, x:=x+1$
- $x:=x+1$
一个 $a_i$ 只能操作一次,问使得数组 $a$ 中的每个数都被 $k$ 整除至少要操作多少次。
题解
记录每个不被 $k$ 整除的 $a_i$ 需要补上的余数,不同次数取较大次数,相同次数取较大模数。
代码
#include <bits/stdc++.h> using namespace std; void solve() { int n, k; cin >> n >> k; map<int, int> cnt; int mx = 0, mx_mod = 0; for (int i = 0; i < n; i++) { int x; cin >> x; if (x % k) { int t = k - x % k; ++cnt[t]; if (cnt[t] > mx) { mx = cnt[t]; mx_mod = t; } else if (cnt[t] == mx) { mx_mod = max(mx_mod, t); } } } cout << max(0LL, (mx - 1LL) * k + mx_mod + 1) << " "; } int main() { int t; cin >> t; while (t--) solve(); }
E1. Reading Books (easy version)
题意
给出 $n$ 本书各自的阅读时长和 Alice 和 Bob 的喜好程度,两个人一起读每本书,问能否每个人都读够 $k$ 本自己喜欢的书以及需要花费的最少时间。
题解
记录二者独自和共同喜好的书,之后取分别阅读二者各自喜欢的书和一起阅读都喜欢的书所用时间的前 $k$ 小即可。
代码
#include <bits/stdc++.h> using namespace std; int main() { int n, k; cin >> n >> k; vector<int> Alice, Bob, Both; for (int i = 0; i < n; i++) { int t, a, b; cin >> t >> a >> b; if (a and !b) Alice.push_back(t); if (!a and b) Bob.push_back(t); if (a and b) Both.push_back(t); } sort(Alice.begin(), Alice.end()); sort(Bob.begin(), Bob.end()); for (int i = 0; i < min(Alice.size(), Bob.size()); i++) { Both.push_back(Alice[i] + Bob[i]); } sort(Both.begin(), Both.end()); cout << (Both.size() < k ? -1 : accumulate(Both.begin(), Both.begin() + k, 0LL)); }