专栏文章
Atcoder ABC 394
题解参与者 1已保存评论 0
文章操作
快速查看文章及其快照的属性,并进行相关操作。
- 当前评论
- 0 条
- 当前快照
- 1 份
- 快照标识符
- @miq5o95c
- 此快照首次捕获于
- 2025/12/03 23:22 3 个月前
- 此快照最后确认于
- 2025/12/03 23:22 3 个月前
倒着处理
CPP#include<bits/stdc++.h>
using namespace std;
int main(){
string s;
cin >> s;
for(int i = s.size() - 1; i >= 0; i--){
if(s[i] == 'A' && s[i - 1] == 'W'){
s[i] = 'C';
s[i - 1] = 'A';
}
}
cout << s << endl;
return 0;
}
经典栈处理括号匹配问题
CPP#include<bits/stdc++.h>
using namespace std;
string s;
int main(){
cin >> s;
stack<char>stk;
map<char, char>mp;
mp[')'] = '(';
mp[']'] = '[';
mp['>'] = '<';
for(int i = 0; i < s.size(); i++){
if(s[i] == '(' || s[i] == '[' || s[i] == '<')
stk.push(s[i]);
else{
if(!stk.size() || stk.top() != mp[s[i]]){
puts("No");
return 0;
}
stk.pop();
}
}
if(stk.empty())
puts("Yes");
else
puts("No");
return 0;
}
思路:考虑回文的本质,如果的路径是回文串,那么就一定满足,其中的路径是回文串, 和是字母相同的边。我们肯定是先计算出的路径,才能扩展出的路径,本质上就是的过程。
每次拓展会让回文串的长度+2
做法:
- 先把所有的 放入队列
- 再把所有的
-的 放入队列 - 的时候 枚举 ,去尝试拓展即可。
#include<bits/stdc++.h>
using namespace std;
const int N = 105;
string s[N];
int dis[N][N];//dis[i][j] -> i到j的最短回文路径长度
int main(){
memset(dis, -1, sizeof(dis));
int n;
cin >> n;
for(int i = 0; i < n; i++) cin >> s[i];
queue<pair<int, int>> que;
for(int i = 0; i < n; i++){ //自己到自己
dis[i][i] = 0;
que.push({i, i});
}
for(int i = 0; i < n; i++){ //任意2个点
for(int j = 0; j < n; j++){
if(i == j)continue;
if (s[i][j] != '-')
dis[i][j] = 1, que.push({i, j});
}
}
while (!que.empty()){
auto cur = que.front();
int x = cur.first, y = cur.second;
que.pop();
for (int i = 0; i < n; i++)//枚举(i,j) 表示从 i->x 和从y->j
for (int j = 0; j < n; j++)
if (s[i][x] != '-' && s[i][x] == s[y][j] && dis[i][j] == -1)
dis[i][j] = dis[x][y] + 2, que.push({i, j});
}
for (int i = 0; i < n; i++){
for (int j = 0; j < n; j++){
cout << dis[i][j] << ' ';
}
cout << endl;
}
return 0;
}
节点为根的子树,有个儿子节点. 整棵子树满足要求的话,这棵子树,至少也要个节点。
记表示以有个儿子时,满足条件的子树的大小;
答案:若,, 否则
设是的某个子节点,与的连接贡献给一个度,所以的儿子只能是个或者是个。
综上:
这是一棵树,先计算子节点,再处理父节点,需要递归处理。
注意:计算时,这里的顺序应该是
CPP#include<bits/stdc++.h>
using namespace std;
const int N = 1e6 + 5;
int n, f[N][5], ans = -1;
vector<int> g[N];
void dfs(int u, int fa){
f[u][0] = 1;
for (auto v : g[u])if (v != fa){
dfs(v, u);
for(int j = 4; j >= 1; j--)// v分支只能选一次,所以逆序
f[u][j] = max(f[u][j], f[u][j - 1] + max(f[v][0], f[v][3]));
//printf("u = %d v = %d:\n", u, v);
//for(int j = 4; j >= 1; j--)
// printf(" j = %d : %d\n", j, f[u][j]);
}
//更新u是根节点的答案
if (f[u][1] >= 5) ans = max(ans, f[u][1]);
ans = max(ans, f[u][4]);
}
int main(){
cin >> n;
for (int i = 1, x, y; i < n; i++){
int u, v;
cin >> u >> v;
g[u].push_back(v);
g[v].push_back(u);
}
memset(f, -0x3f, sizeof f);
dfs(1, 0);
cout << ans << endl;
return 0;
}
相关推荐
评论
共 0 条评论,欢迎与作者交流。
正在加载评论...