日常刷题2025-2-26

日常刷题2025-2-26

E - Palindromic Shortest Path

rating:1500

https://atcoder.jp/contests/abc394/tasks/abc394_e

思路:BFS

做有关回文的题,思考方式应该是考虑长度长的回文如何用长度短的回文得到,以一种递推的方式得到所有回文。

https://www.bilibili.com/video/BV1E2ASeiE8b/?spm_id_from=333.1387.upload.video_card.click&vd_source=4a339d299e165d8fe38b9926c5240eae

代码

#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

https://atcoder.jp/contests/abc394/tasks/abc394_f

思路:树形DP

https://www.bilibili.com/video/BV1E2ASeiE8b/?spm_id_from=333.1387.upload.video_card.click&vd_source=4a339d299e165d8fe38b9926c5240eae

代码

#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;
}

本文作者:califeee

本文链接:https://www.cnblogs.com/califeee/p/18737856

版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。

posted @   califeee  阅读(1)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 提示词工程——AI应用必不可少的技术
· Open-Sora 2.0 重磅开源!
· 周边上新:园子的第一款马克杯温暖上架
点击右上角即可分享
微信分享提示
💬
评论
📌
收藏
💗
关注
👍
推荐
🚀
回顶
收起
  1. 1 404 not found REOL
404 not found - REOL
00:00 / 00:00
An audio error has occurred.