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 longint _, 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,否则输出indexif ((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;
}