C. Canine poetry
时间:2024-07-05
原题:Good Bye 2020 C. Canine poetry
题意
对于一个字符串 \(s\) ,可以对任一字符变为 \(*\) 号,使所有子串不为回文串,即可将 \(babba\) 变为 \(ba*ba\) 使字符串内不存在回文串
数据范围: \(|s|\le 1e5\)
思路
对于某回文字符串,如果是长度为奇数,那么中心的三个字符组成的子串一定是字符串,偶数同理
那么将所有的长度为2和3的回文串进行处理就能达到效果
代码
#include<iostream>
#include<string>
#include<vector>
#include<algorithm>
using namespace std;
#define int long long
int _, n;
vector<bool>vis;
void solve() {
string s;
cin >> s;
int len = s.length();
vis.assign(len, false);
int ans = 0;
for (int i = 1; i < s.length(); i++) {
// 长度为2的回文串,如果没被换过,换后面的字符
if (s[i] == s[i - 1] && !vis[i - 1]) {
vis[i] = true;
ans++;
}
// 长度为3的回文串,同理换第一个
else if (i - 2 >= 0 && s[i] == s[i - 2] && !vis[i - 2]) {
vis[i] = true;
ans++;
}
}
cout << ans << endl;
}
signed main() {
cin >> _;
while (_--)
solve();
return 0;
}
C. Ehab and Path-etic MEXs
时间:2024-07-05
原题:Codeforces Round 628 (Div. 2) C. Ehab and Path-etic MEXs
题意
有一颗 \(n\) 个结点的树,对每条边编号,属于 \([0,n-2]\) ,要求所有对节点对 \((u,v)\) ,其 \(MEX(u,v)\) 的最大值最小
\(MEX(u,v)\) 表示从 \(u\) 到 \(v\) 的唯一简单路径上没出现过的最小编号
理解: 有点绕,就是说,有从 \(u\) 到 \(v\) 假如经过了边1,2,4那么最小的未出现的数就是0,则 \(MEX(u,v)=0\)
即 \(Ans=max(MEX(u,v))\) ,求 \(Ans_{min}\)
思路
首先假定是最简单的情况,也就是一条链,那么简单看一下所有的可能性,可知 \(Ans=n-1\)
所以对于单链,随机存放即可
接下来,如果多了一条链,那么可以观察度大于等于3的点
对于这样的点,无论哪种 \((u,v)\) 的搭配,对于这个点至少有一条边不被覆盖
即只要将0,1,2这最小的三个编号分配在三条分路上,其他编号随意分配,就能实现 \(Ans=2\)
代码
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
#define int long long
#define rep(i,j,k) for(i=(j);i<(k);i++)
typedef pair<int, int> pii;
const int N = 1e5 + 10;
int n, ii;
vector<vector<int>>g;
int u[N], v[N];
void solve() {
cin >> n;
g.assign(n + 1, vector<int>(0));
rep(ii, 0, n - 1) {
cin >> u[ii] >> v[ii];
g[u[ii]].emplace_back(v[ii]);
g[v[ii]].emplace_back(u[ii]);
}
// 如果有大于等于3的度,以存储两个顶点的形式存储每条边,012对应共三条
pii p[3];
int i;
for (i = 0; i < g.size(); i++) {
vector<int> vv = g[i];
if (vv.size() >= 3) {
for (int j = 0; j < 3; j++) {
p[j].first = i;
p[j].second = vv[j];
}
break;
}
}
// 如果没有大于等于3的度,随意输出
if (i == g.size()) {
rep(ii, 0, n - 1) {
cout << ii << endl;
}
return;
}
int ans = 0;
int index = 3;
for (int i = 0; i < n - 1; i++) {
int j;
for (j = 0; j < 3; j++) {
int f = p[j].first, s = p[j].second;
// 如果是012所在的边,输出012,否则输出index
if ((u[i] == f && v[i] == s) || (u[i] == s && v[i] == f)) {
cout << ans << endl;
ans++;
break;
}
}
if (j == 3) {
cout << index++ << endl;
}
}
}
signed main() {
solve();
return 0;
}
标签:07,04,vis,int,暑期,ii,++,include,回文
From: https://www.cnblogs.com/lulaalu/p/18286754