Atcoder ABC 454
Info
42:38 做完D题 结束 后面看看补一下E?
C 题
搜索,找到最长路径的大小
void solve() {
int n, m;
cin >> n >> m;
auto g = vector(n + 1, vector<int>());
for (int i = 0; i < m; i ++) {
int u, v;
cin >> u >> v;
g[u].push_back(v);
}
int ans = 0;
vector<int> vis(n + 1);
vis[0] = 1;
auto dfs = [&](auto &self, int fa, int u) {
if (vis[u]) return;
vis[u] = 1;
ans ++;
debug(fa);debug(u);
for (auto v : g[u]) {
self(self, u, v);
}
};
dfs(dfs, 0, 1);
cout << ans << endl;
}
D 题
第一次遇到字符串的题,第一反应是会不会是dp,但后来发现就是玩一下他的规则,等价于把所有的(xx)都缩成xx,然后看两个字符串一不一样,缩的方法试错了2种,第一次是扫描(xx),发现会错过前面的(,然后又想有点类似括号匹配,但是栈的大小没有这么大,最后想到了是在每次遇到)的时候做判断。
void solve2() {
string a, b;
cin >> a >> b;
int n = a.size(), m = b.size();
string aa, bb;
for (int i = 0; i < n; i ++) {
if (a[i] != ')') aa += a[i];
else {
if (aa.size() >= 3 && aa.substr(aa.size() - 3, 3) == "(xx") {
aa.erase(aa.end() - 3, aa.end() - 2);
} else aa += ')';
}
}
for (int i = 0; i < m; i ++) {
if (b[i] != ')') bb += b[i];
else {
if (bb.size() >= 3 && bb.substr(bb.size() - 3, 3) == "(xx") {
bb.erase(bb.end() - 3, bb.end() - 2);
} else bb += ')';
}
}
debug(aa);debug(bb);
cout << (aa == bb ? "Yes\n" : "No\n");
}
E 题(补题)
想象成国际象棋的棋盘,(1, 1)是黑色,根据n的奇偶性,可以推出(n,n)的颜色和走\(n^2 - 2\)步后最后一步的颜色。
- n奇,(n,n)黑,\(n^2 - 2\)奇,最后一步白
- n偶,(n,n)黑,\(n^2 - 2\)偶,最后一步黑
n为奇时必不可达
路径中点的个数是\(n^2 - 1\)个,\(\frac{n^2}{2} - 1\)个黑,\(\frac{n^2}{2}\)个白,所以跳过点只能是白,即\(a + b\)为奇数
然后如何构造路径?蛇形走位
- 在跳过点之前:先往右走到头,再回头
- 在跳过点那两行,用上下的蛇形走位
- 在跳过点之后,先往左到头,再往右