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;
}
posted @ 2025-06-25 09:47  nuo534202  阅读(1)  评论(0)    收藏  举报