题目大意
给出一个字符串 s s s,要求将 s s s 分为若干个非回文子串,输出一组可行解或输出 − 1 -1 −1 报告无解。
解题思路
我们考虑将连续的相同字符分为一段,然后将没两段或三段合并,得到答案。设划分后有 m m m 段,具体情况如下:
- s s s 本身为非回文串,那么直接输出 s s s 就可以了,此时字串数为 1 1 1;
- 划分后共有偶数段,这种情况直接相邻两段合并即可,子串数为 m 2 \frac{m}{2} 2m;
- 划分后有奇数段,那么这时我们需要将某些段三个合并,情况如下:
- 存在一个段使得它的长度大于 1 1 1 且编号为偶数,这个时候我们将这个段从中间任意一处分为两段,新得到的两段分别与前后两段合并,这时子串数量为 ⌈ m 2 ⌉ \lceil \frac{m}{2} \rceil ⌈2m⌉;
- 存在一个段使得长度大于 1 1 1 且编号为奇数,不妨设它为 a i a_i ai,这个时候我们同样把它从中间某一处断开,使得 a i − 2 ≠ a i ∨ a i + 2 ≠ a i a_{i-2}\not= a_i \vee a_{i+2}\not= a_i ai−2=ai∨ai+2=ai,我们将分开后的两个段分别与前后三个段合并,这时子串个数为 ⌊ m 2 ⌋ \lfloor \frac{m}{2} \rfloor ⌊2m⌋;
- 其他情况无解,输出 − 1 -1 −1;
AC 代码
#pragma GCC optimize(3)
#pragma GCC target("avx")
#pragma GCC optimize("Ofast")
#pragma GCC optimize("inline")
#pragma GCC optimize("-fgcse")
#pragma GCC optimize("-fgcse-lm")
#pragma GCC optimize("-fipa-sra")
#pragma GCC optimize("-ftree-pre")
#pragma GCC optimize("-ftree-vrp")
#pragma GCC optimize("-fpeephole2")
#pragma GCC optimize("-ffast-math")
#pragma GCC optimize("-fsched-spec")
#pragma GCC optimize("unroll-loops")
#pragma GCC optimize("-falign-jumps")
#pragma GCC optimize("-falign-loops")
#pragma GCC optimize("-falign-labels")
#pragma GCC optimize("-fdevirtualize")
#pragma GCC optimize("-fcaller-saves")
#pragma GCC optimize("-fcrossjumping")
#pragma GCC optimize("-fthread-jumps")
#pragma GCC optimize("-funroll-loops")
#pragma GCC optimize("-fwhole-program")
#pragma GCC optimize("-freorder-blocks")
#pragma GCC optimize("-fschedule-insns")
#pragma GCC optimize("inline-functions")
#pragma GCC optimize("-ftree-tail-merge")
#pragma GCC optimize("-fschedule-insns2")
#pragma GCC optimize("-fstrict-aliasing")
#pragma GCC optimize("-fstrict-overflow")
#pragma GCC optimize("-falign-functions")
#pragma GCC optimize("-fcse-skip-blocks")
#pragma GCC optimize("-fcse-follow-jumps")
#pragma GCC optimize("-fsched-interblock")
#pragma GCC optimize("-fpartial-inlining")
#pragma GCC optimize("no-stack-protector")
#pragma GCC optimize("-freorder-functions")
#pragma GCC optimize("-findirect-inlining")
#pragma GCC optimize("-fhoist-adjacent-loads")
#pragma GCC optimize("-frerun-cse-after-loop")
#pragma GCC optimize("inline-small-functions")
#pragma GCC optimize("-finline-small-functions")
#pragma GCC optimize("-ftree-switch-conversion")
#pragma GCC optimize("-foptimize-sibling-calls")
#pragma GCC optimize("-fexpensive-optimizations")
#pragma GCC optimize("-funsafe-loop-optimizations")
#pragma GCC optimize("inline-functions-called-once")
#pragma GCC optimize("-fdelete-null-pointer-checks")
#include<stdio.h>
#include<string.h>
#define N 1000005
int n,m; char s[N];
struct STR{int len;
char ch;}a[N],b[N];
inline bool hw(){ for(int i=1;i<=n;++i)
if(s[i]!=s[n-i+1]) return false;
return true;
}inline void work(){
scanf("%s",s+1); m=0;n=strlen(s+1);
for(int i=1;i<=n;++i) if(s[i]!=s[i-1])
a[++m].ch=s[i],a[m].len=1; else ++a[m].len;
if(!hw()){ printf("YES\n1\n"); printf("%s",s+1);
putchar('\n');return;}if(m==1){puts("NO");return;}
else if(m&1){ bool is=false; for(int i=2;i<m;++i)
if(a[i].len>1&&(i%2==0)){is=true;break;}
if(is){ puts("YES"); printf("%d\n",(m+1)/2);
bool flag=false;for(int i=1;i<=m;++i){ if(i==1||i==m){
for(int j=1;j<=a[i].len;++j) putchar(a[i].ch);
continue;} if(!flag&&a[i].len>1&&(i%2==0)){
putchar(a[i].ch);putchar(' ');
for(int j=1;j<a[i].len;++j) putchar(a[i].ch);
flag=true; continue;
} for(int j=1;j<=a[i].len;++j) putchar(a[i].ch);
if(!flag&&(i%2==0)) putchar(' ');
else if(flag&&(i&1)) putchar(' ');
} putchar('\n');
}else{ is=false;
for(int i=1;i<=m-2;i+=2){ if(i==m) continue;
if(a[i].len!=a[i+2].len){ is=true;break;}
if(a[i].ch!=a[i+2].ch){ is=true;break; }
} if(!is){ int ce=0; for(int i=3;i<=m-2;++i)
if(i&1&&(a[i].len>1)){ is=true;break; }
if(!is){puts("NO");return;}
int pos=0,flag=0; for(int i=1;i<=m;++i)
if((!flag)&&(i&1)&&a[i].len>1&&i!=1&&i!=m){
int l=0,r=a[i].len;
if(r==a[i+2].len) ++l,--r;
if(l==a[i-2].len) ++l,--r;
b[++ce].ch=a[i].ch,b[ce].len=l;
b[++ce].ch=a[i].ch,b[ce].len=r;
pos=ce-1; flag=true;
}else b[++ce]=a[i];
printf("YES\n%d\n",(ce-2)/2);
for(int i=1;i<=ce;i+=2)
if(i+2!=pos){ for(int j=1;j<=b[i].len;++j) putchar(b[i].ch);
for(int j=1;j<=b[i+1].len;++j) putchar(b[i+1].ch);
putchar(' ');
}else{ for(int j=1;j<=b[i].len;++j) putchar(b[i].ch);
for(int j=1;j<=b[i+1].len;++j) putchar(b[i+1].ch);
for(int j=1;j<=b[i+2].len;++j) putchar(b[i+2].ch);
putchar(' '); i+=3;
for(int j=1;j<=b[i].len;++j) putchar(b[i].ch);
for(int j=1;j<=b[i+1].len;++j) putchar(b[i+1].ch);
for(int j=1;j<=b[i+2].len;++j) putchar(b[i+2].ch);
putchar(' '); i+=1;
} putchar('\n'); return;
}
puts("YES");
printf("%d\n",(m-1)/2);
bool flag=false;
for(int i=1;i<=m;i+=2){ if(!flag)
if(a[i].len!=a[i+2].len||a[i].ch!=a[i+2].ch){
for(int j=1;j<=a[i].len;++j) putchar(a[i].ch);
for(int j=1;j<=a[i+1].len;++j) putchar(a[i+1].ch);
for(int j=1;j<=a[i+2].len;++j) putchar(a[i+2].ch);
putchar(' '); ++i; flag=true;continue;
} for(int j=1;j<=a[i].len;++j) putchar(a[i].ch);
for(int j=1;j<=a[i+1].len;++j) putchar(a[i+1].ch);
putchar(' ');
} putchar('\n');
}
}else{ printf("YES\n%d\n",m/2);
for(int i=1;i<=m;i+=2){
for(int j=1;j<=a[i].len;++j) putchar(a[i].ch);
for(int j=1;j<=a[i+1].len;++j) putchar(a[i+1].ch);
putchar(' '); } putchar('\n');
}
} signed main(){
int T;scanf("%d",&T);
while(T--) work();
}