AtCoder Beginner Contest 049
A - UOIAUAI
#include <bits/stdc++.h>
using namespace std;
using i64 = long long;
int main() {
ios::sync_with_stdio(false), cin.tie(nullptr);
char c;
cin >> c;
if (c == 'a' || c == 'e' || c == 'i' || c == 'o' || c == 'u') cout << "vowel";
else cout << "consonant";
return 0;
}
B - Thin
观察样例发现规律后直接模拟。
#include <bits/stdc++.h>
using namespace std;
using i64 = long long;
int main() {
ios::sync_with_stdio(false), cin.tie(nullptr);
int H, W;
cin >> H >> W;
vector<char> v(W);
for (int i = 0; i < H; i++) {
for (int j = 0; j < W; j++) {
cin >> v[j];
cout << v[j];
}
cout << "\n";
for (int j = 0; j < W; j++) cout << v[j];
cout << "\n";
}
return 0;
}
C - Daydream
考虑到 \(\rm erase(r)\) 如果出现在 \(\rm dreamer\) 后面,即形如 \(\rm dreamerase\) 时,若从前往后若先分析 \(\rm dreamer\) 可能会判断错误,不如从后往前分析。
将备选的字符串设置为数组,遍历。但凡与其中某个字符串匹配就用 \(\rm string\) 的 \(\rm pop\_back\) 弹出该字符串,然后再从头开始遍历字符串数组。如果最后原本的字符串被删除为 \(0\),则说明匹配成功。
若匹配标志为 \(\rm false\),说明匹配失败。
#include <bits/stdc++.h>
using namespace std;
using i64 = long long;
int main() {
ios::sync_with_stdio(false), cin.tie(nullptr);
string s;
cin >> s;
vector<string> v({"erase", "eraser", "dream", "dreamer"});
while (1) {
bool match = false;
for (auto i : v) {
int len = i.size();
if (s.size() >= len && i == s.substr(s.size() - len, len)) {
match = true;
while (len--) s.pop_back();
break;//匹配成功一个串,break掉,下一轮重新开始遍历字符串数组。
}
}
if (!match) {//匹配失败
cout << "NO";
return 0;
}
if (s.empty()) {//如果字符串最后为空,则说明所有字符均已匹配成功
cout << "YES";
return 0;
}
}
return 0;
}
D - Connectivity
道路涉及连通性的问题,即同一道路相互连接的各条道路之间都可相互通行,因此可以使用两个并查集,一个记录道路,一个记录铁路。
不管是道路还是铁路,对于每个城市来说一定与其连通的肯定是它在该并查集的祖先,(城市在该并查集中有祖先即说明该城市在并查集中)
一开始想数组 \(f[i][j]\) 表示与 \(i\) 和 \(j\) 分别连通的城市个数,那么对于城市 \(u\),答案即为 \(\rm f[find(u,p_1)][find(u,p_2)]\)。初始化过程就是遍历每一个城市,\(\rm f[find(i,p_1)][find(i,p_2)]\)++。
发现空间复杂度为 \(O(n^2)\) ,舍弃。

观察到,对于每个点,我们只会把这个数组的一个位置+1,所以至多用到 \(N\) 个位置。可以开 \(\rm map\)<\(\rm pair\)<\(\rm int,int\)>\(\rm,int\)>,将 \((x,y)\) 当成坐标映射,即可实现空间复杂度 \(O(n)\)。
#include <bits/stdc++.h>
using namespace std;
using i64 = long long;
int p1[200005], p2[200005];
int find(int x, int* p) {
if (x != p[x]) return p[x] = find(p[x], p);
return p[x];
}
void merge(int x, int y, int* p) {
p[find(x, p)] = find(y, p);
}
int main() {
ios::sync_with_stdio(false), cin.tie(nullptr);
int N, K, L;
cin >> N >> K >> L;
for (int i = 1; i <= N; i++) {
p1[i] = i;
p2[i] = i;
}
for (int i = 1; i <= K; i++) {
int a, b;
cin >> a >> b;
merge(a, b, p1);
}
for (int i = 1; i <= L; i++) {
int c, d;
cin >> c >> d;
merge(c, d, p2);
}
map<pair<int, int>, int> ans;
for (int i = 1; i <= N; i++) {
ans[{find(i, p1), find(i, p2)}]++;
}
for (int i = 1; i <= N; i++) cout << ans[{find(i, p1), find(i, p2)}] << " ";
return 0;
}
\(\rm plus:\) 可以使用 \(\rm AtCoder\) 自己的并查集板子:
#include<bits/stdc++.h>
#include<atcoder/dsu>
using namespace std;
using namespace atcoder;
int main() {
int N, K, L;
cin >> N >> K >> L;
dsu uf1(N), uf2(N);
for (int i = 0; i < K; i++) {
int p, q;
cin >> p >> q;
p--, q--;
uf1.merge(p,q);
}
for (int i = 0; i < L; i++) {
int l, r;
cin >> l >> r;
l--, r--;
uf2.merge(l,r);
}
map<pair<int, int>, int> m;
for (int i = 0; i < N; i++) m[{uf1.leader(i),uf2.leader(i)}]++;
for (int i = 0; i < N; i++) cout << m[{uf1.leader(i),uf2.leader(i)}] << " ";
return 0;
}

浙公网安备 33010602011771号