首先一定有解,考虑归纳法证明
首先 $n<=3$ 时显然
考虑 $n=4$ 时,那么因为 $s[1]!=s[2],s[3]!=s[4]$ ,并且 $s[i] \in {a,b,c}$ 由鸽巢原理显然意味着 $s[1],s[2]$ 至少有一个等于 $s[3]$ 或 $s[4]$
那么我们从中间往两边延伸,每左边两个就和右边两个组合,这样每四个位置就有两个位置会贡献回文字符,那么一定有解
注意如果 $n \mod 4=2$ 或者 $n \mod 4=3$ 时最后会剩下几个不能组成左边两个右边两个,那么我们回文长度搞成奇数即可(中间先选择一个作为回文中心)
#include<iostream> #include<cstdio> #include<algorithm> #include<cstring> #include<cmath> #include<vector> using namespace std; typedef long long ll; inline int read() { int x=0,f=1; char ch=getchar(); while(ch<'0'||ch>'9') { if(ch=='-') f=-1; ch=getchar(); } while(ch>='0'&&ch<='9') { x=(x<<1)+(x<<3)+(ch^48); ch=getchar(); } return x*f; } const int N=2e6+7; int n; char s[N]; vector <int> ans; void work(int l,int r) { for(; l>=2&&r<=n-1; l-=2,r+=2) { vector <int> cnt[3]; cnt[s[l-1]-'a'].push_back(l-1); cnt[s[r+1]-'a'].push_back(r+1); cnt[s[l]-'a'].push_back(l); cnt[s[r]-'a'].push_back(r); for(int k=0;k<3;k++) if(cnt[k].size()>1) { ans.push_back(cnt[k][0]), ans.push_back(cnt[k][1]); break; } } } int main() { scanf("%s",s+1); n=strlen(s+1); int mid=1+n>>1; if(n%4) { ans.push_back(mid); work(mid-1,mid+1); } else work(mid,mid+1); sort(ans.begin(),ans.end()); for(auto p: ans) printf("%c",s[p]); puts(""); return 0; }