Codeforces Round #692 (Div. 2, based on Technocup 2021 Elimination Round 3)
Codeforces Round #692 (Div. 2, based on Technocup 2021 Elimination Round 3)
從傳智杯到牛客到cf, 一條龍, 腦子有點呆
A - In-game Chat
int main() { IOS; for (cin >> _; _; --_) { cin >> n >> s + 1; int c = 0; per (i, n, 1) if (s[i] == ')') ++c; else break; cout << (c * 2 > n ? "YES\n" : "NO\n"); } return 0; }
B - Fair Numbers
1~9的公倍數為2520, 故最多檢測2519個數, 就能找到最小的公平數
bool check(ll x) { ll y = x; while (x) { if (x % 10 == 0) { x /= 10; continue; } if (y % (x % 10)) return 0; x /= 10; } return 1; } int main() { IOS; for (cin >> _; _; --_) { ll n; cin >> n; for (ll i = n; i <= 1e18; ++i) if (check(i)) { cout << i << '\n'; break; } } return 0; }
C - Peaceful Rooks
按理來說每個數(不在對角線上的)移動一次剛剛好
但是他要就不能相互攻擊, 有的就要先讓出個位置了, 比如 (2, 3), (3, 4) (4, 2)
成了個環, 要先有個點到其他位置呆著所以總步數 +1
就用並查集判有多少個環就行了
int find(int x) { return x == f[x] ? x : f[x] = find(f[x]); } int main() { IOS; for (cin >> _; _; --_) { cin >> n >> m; rep (i, 1, n) f[i] = i; ll ans = 0; rep (i, 1, m) { int x, y; cin >> x >> y; if (x == y) continue; ++ans; x = find(x), y = find(y); if (x == y) ++ans; else f[y] = x; } cout << ans << '\n'; } return 0; }
D - Grime Zoo
當?序列為 111..000 or 000...111 or 00..00 or 11..11 時最小
不存在 01, 10相間, 這個證明有點費事, 就整個不能 0101的把 不能 11000011000的自己證吧
對於 ..?..?.?.?.. 問號(這四個問號在是相鄰的)對應 0101, 記 st[i][0, 1, 2] 表示從1~i中有多少個 0, 1, ?, ed[i][0,1,2] 同理
0101 下標分別為 a, b, c, d 且 a < b < c < d, 序列總長為n
對於b和c貢獻為 st[b][0] * x + ed[b][0] * y + st[c][1] * y + ed[c][1] * x
將序列變為 0001 bc的貢獻為: (st[b][1] - 1(b變成0了-1)) * x + (ed[b][1] - 1) * y + (st[c][1] - 1) * y + (ed[c][1] - 1) * x
不論變成 0001 還是 0111 都比 0101 要小, 當然肉眼也可見,
想想也因該發現 00000, 1111最小畢竟為0, 但是我們能改的位置有限, 記我們只能改 問號為 1 or 0
拋棄不能改的位置也理應是 00000, 1111是最小, 但還要考慮 不能改的位置那隻好妥協成了 00001111.. or 11111000.. or 00000.. or 111..
int main() {
IOS; ll x, y; cin >> s >> x >> y;
rep (i, 1, s.size()) rep (j, 0, 2)
st[i][j] = st[i - 1][j] + (j < 2 ? s[i - 1] == '0' + j : s[i - 1] == '?');
per (i, s.size(), 1) rep (j, 0, 2)
ed[i][j] = ed[i + 1][j] + (j < 2 ? s[i - 1] == '0' + j : s[i - 1] == '?');
int cnt0 = 0, cnt1 = 0;
ll t = 0, res, ans;
rep (i, 1, s.size())
if (s[i - 1] == '0') ++cnt0, t += cnt1 * y;
else ++cnt1, t += cnt0 * x;
res = ans = t;
rep (i, 1, s.size()) if (s[i - 1] == '?') {
res -= (st[i - 1][0] + st[i - 1][2]) * x + ed[i + 1][0] * y;
res += st[i - 1][1] * y + (ed[i + 1][1] + ed[i + 1][2]) * x;
umin(ans, res);
} res = t;
per (i, s.size(), 1) if (s[i - 1] == '?') {
res -= st[i - 1][0] * x + (ed[i + 1][0] + ed[i + 1][2]) * y;
res += (st[i - 1][1] + st[i - 1][2]) * y + ed[i + 1][1] * x;
umin(ans, res);
}
cout << ans;
return 0;
}