Atcoder Beginner Contest 386
比赛链接: Atcoder Beginner Contest 386
Github 链接: ABC386
A - Full House 2
如果四张卡片有三张相同的或者两两相同,并且四张不完全相同,输出 \(Yes\),否则输出 \(No\)。
时间复杂度:\(O(1)\)。
#include <bits/stdc++.h>
using namespace std;
int main() {
ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
int a[5];
for (int i = 1; i <= 4; i++) cin >> a[i];
sort(a + 1, a + 5);
if (a[1] == a[4]) puts("No");
else if (a[1] == a[2] && a[2] == a[3]) puts("Yes");
else if (a[2] == a[3] && a[3] == a[4]) puts("Yes");
else if (a[1] == a[2] && a[3] == a[4]) puts("Yes");
else puts("No");
return 0;
}
B - Calculator
根据题意模拟,具体实现看代码。
时间复杂度:\(O(N)\)。
#include <bits/stdc++.h>
using namespace std;
int main() {
ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
string s; cin >> s;
int n = s.size(), ans = 0;
s = " " + s;
for (int i = 1; i <= n; i++) {
if (s[i] >= '1' && s[i] <= '9') ans++;
else {
int j;
for (j = i; j + 1 <= n && s[j + 1] == '0'; j++);
ans += (j - i + 2) / 2;
i = j;
}
}
cout << ans << endl;
return 0;
}
C - Operate 1
双指针从字符串两端开始进行匹配,只允许有一个失配的地方,最后两个指针应该都指向失配的那个位置。
时间复杂度:\(O(N)\)。
#include <bits/stdc++.h>
using namespace std;
int main() {
ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
int k; string s, t;
cin >> k >> s >> t;
if (abs((int)(s.size() - t.size())) > 1) {
puts("No");
return 0;
}
int l = 0, r = max(t.size(), s.size()) - 1;
if (t.size() == s.size()) {
while (l < r && s[l] == t[l]) l++;
while (l < r && s[r] == t[r]) r--;
} else if (t.size() > s.size()) {
while (l < r && s[l] == t[l]) l++;
while (l < r && s[r - 1] == t[r]) r--;
} else {
while (l < r && s[l] == t[l]) l++;
while (l < r && s[r] == t[r - 1]) r--;
}
if (l == r) puts("Yes");
else puts("No");
return 0;
}
D - Diagonal Separation
对于所有给出的 \((x_i, y_i, c_i)\),以 \(x_i\) 为第一关键字,\(c_i\) 为第二关键字进行排序。对于相同的 \(x\),\(c_i = B\) 的 \(y\) 值要小于所有的 \(c_i = W\) 的 \(y\) 值。对于不同的 \(x\),\(x\) 较大的那一行 \(c_i = B\) 对应的最大的 \(y\) 值要小于上一行 \(c_i = W\) 最小的 \(y\) 值。
时间复杂度:\(O(M\log M)\)。
#include <bits/stdc++.h>
using namespace std;
const int M = 2e5 + 10;
int n, m;
struct node { int x, y; char c; } p[M];
int main() {
ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
cin >> n >> m;
for (int i = 1; i <= m; i++) cin >> p[i].x >> p[i].y >> p[i].c;
sort(p + 1, p + m + 1, [](const node &a, const node &b){
if (a.x == b.x) return a.c > b.c;
return a.x < b.x;
});
n++;
for (int i = 1; i <= m; i++) {
if (p[i].c == 'W') n = min(n, p[i].y);
if (p[i].c == 'B') {
if (p[i].y >= n) {
cout << "No" << endl;
return 0;
}
}
}
cout << "Yes" << endl;
return 0;
}
E - Maximize XOR
由于 \(C_n^k \le 10^6\),实际上的 \(min(k, n - k) \le 10\),因此可以直接搜索出每一种答案。对于 \(k > \lceil \frac{n}{2} \rceil\),可以令 \(k = n - k\),然后答案为搜索出来的答案 \(\text{XOR}\) \(A_1 \oplus A_2 \oplus \cdots \oplus A_n\)。
时间复杂度:\(O(2^{min(K, N - K)})\)。
#include <bits/stdc++.h>
using namespace std;
#define int long long
const int N = 2e5 + 10;
int n, k, a[N], ans = 0, flag = 0, sum = 0;
inline int read() {
int x = 0, f = 1; char c = getchar();
while (c < '0' || c > '9') { if (c == '-') f = -1; c = getchar(); }
while (c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar();
return x * f;
}
void dfs(int cur = 1, int num = 0, int tot = 0) {
if (num >= k) {
ans = max(ans, tot ^ sum);
return;
}
if (cur > n) return;
dfs(cur + 1, num + 1, tot ^ a[cur]);
dfs(cur + 1, num, tot);
}
signed main() {
n = read(), k = read();
for (int i = 1; i <= n; i++) a[i] = read();
if (k >= (n + 1) / 2) {
k = n - k;
flag = 1;
}
if (flag)
for (int i = 1; i <= n; i++) sum ^= a[i];
else sum = 0;
dfs();
printf("%lld\n", ans);
return 0;
}
F - Operate K
首先,可以设 \(dp_{i, j}\) 为考虑到字符串 \(s\) 的第 \(i\) 位,字符串 \(t\) 的第 \(j\) 位时,需要进行的操作次数,但是由于 \(|S|, |T| \le 5 \times 10^5\),时间和空间都无法接受。
可以注意到,当 \(|i - j| > k\) 的时候,\(dp_{i, j} > k\),所以只需要考虑 \(|i - j| \le k\) 的情况。
重新设 \(dp_{i, pos}\) 表示考虑到字符串 \(s\) 的第 \(i\) 位,字符串 \(t\) 的第 \(j\) 位时,需要进行的操作次数,令 \(pos = j - i + 30\),这样 \(pos\) 与 \(j\) 就存在一个 一 一 对应的关系,每一对 \((i, j)\) 在 \(dp\) 数组中都有一个位置进行表示。
时间复杂度:\(O(NK)\)。
#include <bits/stdc++.h>
using namespace std;
const int N = 5e5 + 10;
int k, dp[N][60];
string s, t;
int get(int x, int y) {
if (abs(x - y) > k) return INT_MAX;
return dp[x][y - x + 30];
}
int main() {
ios::sync_with_stdio(false); cin.tie(0);
cin >> k >> s >> t;
memset(dp, 0x3f, sizeof(dp));
for (int j = 1; j <= k; j++) dp[0][j + 30] = j;
for (int i = 1; i <= k; i++) dp[i][30 - i] = i;
dp[0][30] = 0;
int n = s.size(), m = t.size();
s = " " + s, t = " " + t;
for (int i = 1; i <= n; i++) {
for (int pos = 0; pos < 60; pos++) {
int j = pos - 30 + i;
if (j < 1 || j > m) continue;
int tmp = INT_MAX;
tmp = min(tmp, get(i - 1, j - 1) + 1);
tmp = min(tmp, min(get(i - 1, j), get(i, j - 1)) + 1);
if (s[i] == t[j]) tmp = min(tmp, get(i - 1, j - 1));
dp[i][pos] = tmp;
}
}
puts(get(n, m) <= k ? "Yes" : "No");
return 0;
}

浙公网安备 33010602011771号