【补题】The 2024 ICPC Kunming Invitational Contest I. Left Shifting 2
题意:给个字符串,你可以随意位移字符串,之后你可以任意次更改字符,问怎么样可以让所有字符都没有相邻相同的字符,且操作次数最少。
思路:
1.自己试图做几次操作就会很明确,相同的连续字符串,只要xaxax这么修改就可以了,也就是把中间偏后的修改掉。但是当长度为偶数的时候,如果把最后一个转移到头,例如xxxxa变成xaxxx,就可以有效减少一次操作。
2.其实最大的问题在于给你的字符串本身可能是被切割过的,所以应该把头拼到尾部或者尾部拼到头部,然后进行判断,代码苦手为这篇出个补题的原因就是自己vp的时候最后还是叫队友写的代码,同时不要忘记特判整个字符串相同,因为这样位移操作分割不掉也没有意义。
3.最后直接计算所有连续字符串的长度/2,如果不是全一样且有偶数连续字符串,那么就进行-1操作。
代码:
#include<bits/stdc++.h>
using namespace std;
#define int long long
#define int128 __int128
#define endl '\n'
#define IOS ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
const int N = 2e5+10;
const int INF = 1e18;
const int MOD = 2023;void solve(){string s;cin >> s;int n=s.size();s=s+s;map<int,int> mp;int start=0;while(s[start]==s[0] && start<n)start++;for(int i=start;i<n+start;i++){int j=i;while(j<s.size() && j-i<n && s[j]==s[i]){j++;}mp[(j-i)]++;i=j-1;}int ans=0;int f=0;int jud=1;for(auto u : mp){if(u.first==n) jud=0;ans+=u.first/2*u.second;f=max(f,(u.first+1)%2);}if(jud && f){cout << ans-1 << endl;}else cout << ans << endl;
}signed main(){IOS;int t=1;cin >> t;while(t--){solve();}
}
感觉vp的时候真是超级糊涂……这居然卡了我很久很久,其实是纯签到题