日常刷题2025-2-26
日常刷题2025-2-26
E - Palindromic Shortest Path
rating:1500
思路:BFS
做有关回文的题,思考方式应该是考虑长度长的回文如何用长度短的回文得到,以一种递推的方式得到所有回文。
代码
#include <bits/stdc++.h>
using namespace std;
const int N = 105;
const int N2 = N * N;
int n, ans[N][N];
char s[N][N];
int q[N2][2];
int main() {
scanf("%d", &n);
for(int i = 1; i <= n; i++) {
scanf("%s", s[i] + 1);
}
int hd = 1, tl = 0;
memset(ans, 0x3f, sizeof(ans));
for(int i = 1; i <= n; i++) {
ans[i][i] = 0;
q[++tl][0] = i; q[tl][1] = i;
// (i, i) : 0 入队
}
for(int i = 1; i <= n; i++) {
for(int j = 1; j <= n; j++) {
if(i != j && s[i][j] != '-') {
ans[i][j] = 1;
q[++tl][0] = i; q[tl][1] = j;
// (i, j) : 1 入队
}
}
}
while(hd <= tl) {
int u = q[hd][0], v = q[hd][1];
// 取出状态 (u, v)
hd++;
for(int i = 1; i <= n; i++) if(s[i][u] != '-') {
for(int j = 1; j <= n; j++) if(s[v][j] == s[i][u]) {
// 扩展后的状态 (i, j)
if(ans[i][j] == 0x3f3f3f3f) {
ans[i][j] = ans[u][v] + 2;
q[++tl][0] = i; q[tl][1] = j;
}
}
}
}
for(int i = 1; i <= n; i++) {
for(int j = 1; j <= n; j++) {
if(ans[i][j] == 0x3f3f3f3f) {
printf("-1 ");
} else {
printf("%d ", ans[i][j]);
}
}
puts("");
}
return 0;
}
F - Alkane
rating:1500
思路:树形DP
代码
#include <bits/stdc++.h>
using namespace std;
const int N = 2e5 + 5;
int n, d[N], f[N][2], ans;
vector<int> G[N];
bool vis[N];
void dfs(int u) {
vis[u] = true;
vector<int> tmp;
for(int v : G[u]) if(d[v] >= 4 && !vis[v]) {
dfs(v);
tmp.push_back(f[v][1]);
}
sort(tmp.rbegin(), tmp.rend()); // 从大到小把儿子排序了
f[u][1] = 1; // 选最大的三个儿子
for(int i = 0; i < tmp.size() && i < 3; i++) {
f[u][1] += tmp[i];
}
// f[u][0] 选最大的四个儿子
f[u][0] = f[u][1];
if(tmp.size() >= 4) f[u][0] += tmp[3];
ans = max(ans, f[u][0]);
}
int main() {
scanf("%d", &n);
for(int i = 1; i < n; i++) {
int u, v;
scanf("%d %d", &u, &v);
G[u].push_back(v);
G[v].push_back(u);
d[u]++;
d[v]++;
}
for(int i = 1; i <= n; i++) {
if(d[i] >= 4 && !vis[i]) {
dfs(i);
}
}
if(ans == 0) printf("-1\n");
else printf("%d\n", ans * 3 + 2);
return 0;
}

浙公网安备 33010602011771号