题解 P5799 【[SEERC2019]Cycle String?】

· · 题解

$\ \ \ \ \ \ \ $我们无法找到内在的规律,考虑构造。 - 如果出现最多的字母出现次数小于 $n$,显然可以发现相同插进一个,可以的。 - 否则: - 如果只有一种字母,显然不能。 - 如果有两种字母,并且另外一种字母出现次数小于 2,仍然不能。 - 否则可以。首先输出 $n$ 个出现次数最多的字母,然后任意放一个其他字符,放完出现次数最多的字母,最后把剩下的字母全部输出,按出现最多的字母出现次数小于 $n$ 的方式输出。 ```cpp #include<cstdio> #include<algorithm> #include<cstring> using namespace std; char str[1000005]; int n,cnt[27]; int main(){ scanf("%s",str+1); n=strlen(str+1); for(int i=1;i<=n;++i) ++cnt[str[i]-'a']; bool flag=false; int acs=0,where=0; for(int i=0;i<=25;++i) { if(cnt[i]) ++acs; if(cnt[i]>n/2) { flag=true; where=i; } } if(flag) { if(acs==1) return puts("NO")&0; if(acs==2 && n-cnt[where]<=2) return puts("NO")&0; puts("YES"); for(int i=1;i<=n/2;++i) putchar(where+'a'); for(int i=0;i<=25;++i) { if(cnt[i] && i!=where) { putchar(i+'a'); --cnt[i]; break; } } for(int i=1;i<=cnt[where]-n/2;++i) putchar(where+'a'); for(int i=0;i<=25;++i) if(i!=where) for(int j=1;j<=cnt[i];++j) putchar(i+'a'); } else { puts("YES"); for(int i=0;i<=25;++i) for(int j=1;j<=cnt[i];++j) putchar(i+'a'); } return 0; } ```