Restoration of string
题目描述
传送门:http://codeforces.com/problemset/problem/886/D
题解
感觉这题思路好精妙。
考虑一个字符串,如果它是most frequent的,那么对这个串中任意相邻的一对元素,如ab,则在good string中对于任意一个a后面都必须跟着一个b。否则a就是一个比ab更常见的子串。
因此,对于读入的字符串,我们可以把相邻的字符串连边。最后生成的这张图必须由一堆不相交的链组成的。按照字典序把这个串搞出来就好了。
代码
#include<bits/stdc++.h>
#define N 30
#define M 100005
using namespace std;
int n,cnt,tot,flag[N],next[N],d[N],check[N];
char s[M],ans[N];
int main()
{
int len,a,b;
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
scanf(" %s",s+1);len=strlen(s+1);
for(int i=1;i<=len;i++)flag[s[i]-'a'+1]=1;
for(int i=1;i<len;i++)
{
a=s[i]-'a'+1;b=s[i+1]-'a'+1;
if(next[a]&&next[a]!=b){printf("NO\n");return 0;}
next[a]=b;d[b]++;
}
}
for(int i=1;i<=26;i++)
{
if(!flag[i]){cnt++;continue;}
if(d[i])continue;
for(int x=i;x;x=next[x])
{
if(check[x]){printf("NO\n");return 0;}
check[x]=1;ans[++tot]=x+'a'-1;cnt++;
}
}
if(cnt<26){printf("NO\n");return 0;}
for(int i=1;i<=tot;i++)printf("%c",ans[i]);
printf("\n");
return 0;
}