UNIQUE VISION Programming Contest 2025 Spring (AtCoder Beginner Contest 398) (A~F) 补题+题解

A - Doors in the Center

签到题,直接构造即可。
点击查看代码

复制代码
#include<bits/stdc++.h>
using namespace std;
#define int long long
const int N = 1e6 + 10;

signed main() {
	int n;
	cin >> n;
	if (n % 2 == 1) {
		for (int i = 1; i <= n / 2; i++) {
			cout << '-';
		}
		cout << "=";
		for (int i = 1; i <= n / 2; i++) {
			cout << '-';
		}
	} else {
		for (int i = 1; i <= n / 2 - 1; i++) {
			cout << '-';
		}
		cout << "==";
		for (int i = 1; i <= n / 2 - 1; i++) {
			cout << '-';
		}
	}
}
/*
*/

B - Full House 3

有两种三个以上的相同的或者一种三个以上相同一种两个以上相同便可以满足葫芦的条件。
点击查看代码

复制代码
#include<bits/stdc++.h>
using namespace std;
#define int long long
const int N = 1e6 + 10;

signed main() {
	int n = 7;
	map<int, int> mp;
	set<int> se;
	for (int i = 1; i <= n; i++) {
		int x;
		cin >> x;
		mp[x]++;
		se.insert(x);
	}
	int f = 0, ff = 0;
	for (auto t : se) {
		if (mp[t] >= 3) f++;
		else if (mp[t] >= 2) ff++;
	}
	if (f >= 2 || (f == 1 && ff >= 1)) {
		cout << "Yes\n";
	} else {
		cout << "No\n";
	}
}
/*
*/

C - Uniqueness

暴力枚举。
点击查看代码

复制代码
#include<bits/stdc++.h>
using namespace std;
#define int long long
const int N = 1e6 + 10;

signed main() {
	int n;
	cin >> n;
	map<int, int> mp;
	vector<int> a(n + 1);
	for (int i = 1; i <= n; i++) {
		cin >> a[i];
		mp[a[i]]++;
	}
	int ans = -1, id = -1;
	for (int i = 1; i <= n; i++) {
		if (mp[a[i]] == 1) {
			if (a[i] > ans) {
				ans = a[i];
				id = i;
			}
		}
	}
	cout << id << '\n';
}
/*
*/

D - Bonfire

\((0,0)\)点每次都会刷新新的烟雾,对于每次移动是否可以覆盖高桥只需要看前面哪个刷新的烟雾可以到达高桥,如果有则是1,没有则是0。

实现上可以用两个\(sum\)数组记录东西和南北的移动量,二分去查找。

当然其实也有实现更简便的方法。
点击查看代码

复制代码
#include<bits/stdc++.h>
using namespace std;
#define int long long
const int N = 1e6 + 10;
signed main() {
	ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
	int n, r, c;
	cin >> n >> r >> c;
	string s;
	cin >> s;
	//n r-1
	//w c-1
	//s r+1
	//e c+1
	s = ' ' + s;
	vector<int> sum1(n + 1), sum2(n + 1);
	for (int i = 1; i <= n; i++) {
		sum1[i] = sum1[i - 1], sum2[i] = sum2[i - 1];
		if (s[i] == 'N') sum1[i] -= 1;
		if (s[i] == 'S') sum1[i] += 1;
		if (s[i] == 'W') sum2[i] -= 1;
		if (s[i] == 'E') sum2[i] += 1;
	}
//	for (int i = 1; i <= n; i++) {
//		cout << sum1[i] << " \n"[i == n];
//	}
//	for (int i = 1; i <= n; i++) {
//		cout << sum2[i] << " \n"[i == n];
//	}
	map<pair<int, int>, vector<int>> mp;
	mp[ {0, 0}].push_back(1);
	for (int i = 1; i <= n; i++) {
		mp[ {sum1[i], sum2[i]}].push_back(i + 1);
	}
	string ans;
	for (int i = 1; i <= n; i++) {
		int x = sum1[i], y = sum2[i];
		int nex = x - r, ney = y - c;
		if (mp[ {nex, ney}].size() == 0 ) {
			ans += "0";
			continue;
		}
		if (mp[ {nex, ney}].back() <= i) {
			ans += "1";
			continue;
		}
		int l = upper_bound(mp[ {nex, ney}].begin(), mp[ {nex, ney}].end(), i) - mp[ {nex, ney}].begin();
		if (mp[ {nex, ney}][l] <= i) ans += "1";
		else {
			if (l != 0) l--;
			else {
				ans += "0";
				continue;
			}
			if (mp[ {nex, ney}][l] <= i) ans += "1";
		}
	}
	cout << ans << '\n';
}
/*
10 1 2
NEESESWEES
2 2
2 1
2 0

6 -2 1
NNEEWS

*/

E - Tree Game

交互题,通过对每个点\(bfs\)可以将所有 u -\>v 经过点集为偶数的组合记录下来,如果组合的数量是奇数那么是\(first\),否则是\(second\)。然后根据对手操作输出合适的\((u,v)\)。
点击查看代码

复制代码
#include<bits/stdc++.h>
using namespace std;
#define int long long
const int N = 1e6 + 10;
signed main() {
	ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
	int n;
	cin >> n;
	vector<vector<int>> g(n + 10);
	vector<int> d(n + 10), e(n + 10);
	for (int i = 1; i < n; i++) {
		int u, v;
		cin >> u >> v;
		d[u]++;
		e[v]++;
		g[u].push_back(v);
		g[v].push_back(u);
	}
	queue<pair<int, int>> qq;
	map<pair<int, int>, int> mp;
	for (int i = 1; i <= n; i++) {
		vector<int> st(n + 1), dis(n + 1, 0);
		queue<int> q;
		q.push(i);
		st[i] = 1;
		while (q.size()) {
			int u = q.front();
			q.pop();
			for (auto v : g[u]) {
				if (st[v] == 0) {
					q.push(v);
					st[v] = 1;
					dis[v] = dis[u] + 1;
				}
			}
		}
		for (int j = 1; j <= n; j++) {
//			cout << dis[j] << " \n"[j == n];
			if (j != i) {
				if ((dis[j] + 1) % 2 == 0 && dis[j] + 1 != 2) {
					if (mp[ {i, j}] == 0) {
						qq.push({i, j});
						mp[ {i, j}] = 1;
						mp[ {j, i}] = 1;
					}
				}
			}
		}
	}
	map<pair<int, int>, int> st;
//	cout << qq.size() << '\n';
	if (qq.size() % 2 == 1) {
		cout << "First" << endl;
		while (qq.size()) {
			while (qq.size() && st[qq.front()] == 1) qq.pop();
			pair<int, int> t = qq.front();
			qq.pop();
			cout << t.first << ' ' << t.second << endl;
			int u, v;
			cin >> u >> v;
			st[ {u, v}] = 1;
			st[ {v, u}] = 1;
			if (u == -1 && v == -1) return 0;
		}
	} else {
		cout << "Second" << endl;
		while (qq.size()) {
			int u, v;
			cin >> u >> v;
			st[ {u, v}] = 1;
			st[ {v, u}] = 1;
			if (u == -1 || v == -1) return 0;
			while (qq.size() && st[qq.front()] == 1) qq.pop();
			if (qq.size() == 0)return 0;
			pair<int, int> t = qq.front();
			qq.pop();
			cout << t.first << ' ' << t.second << endl;
		}
		int u, v;
		cin >> u >> v;
		if (u == -1 && v == -1) return 0;
	}
	return 0;
}
/*
6
1 2
2 3
3 4
4 5
5 6

5
1 2
1 3
2 4
2 5
*/

F - ABCBA

这个题就是比较简单,很容易想到找最长的 \([l,n]\) 回文串,代码实现使用的哈希。
点击查看代码

复制代码
#include<bits/stdc++.h>
using namespace std;
#define int long long
#define ull unsigned long long
const int N = 1e6 + 10, base = 13331;
ull hs[N], pa[N], fhs[N], fpa[N];
ull get(int l, int r) {
	return hs[r] - hs[l - 1] * pa[r - l + 1];
}
ull getf(int l, int r) {
	return fhs[r] - fhs[l - 1] * fpa[r - l + 1];
}
signed main() {
	ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
	string s;
	cin >> s;
	string yu = s;
	int n = s.size();
	s = ' ' + s;
	pa[0] = 1, fpa[0] = 1;
	for (int i = 1; i <= n; i++) {
		pa[i] = pa[i - 1] * base;
		hs[i] = hs[i - 1] * base + s[i];
	}
	reverse(yu.begin(), yu.end());
	string fs = yu;
	reverse(yu.begin(), yu.end());
	fs = ' ' + fs;
	for (int i = 1; i <= n; i++) {
		fpa[i] = fpa[i - 1] * base;
		fhs[i] = fhs[i - 1] * base + fs[i];
	}
	int k = n;
	for (int i = 1; i <= n; i++) {
		ull a = get(i, n);
		ull b = getf(1, n - i + 1);
		if (a == b) {
			k = i - 1;
			break;
		}
	}
	string ans = yu;
	for (int i = k; i >= 1; i--) {
		ans += s[i];
	}
	cout << ans << '\n';
}
/*
*/