1. 程式人生 > >【CF886D】Restoration of string 亂搞

【CF886D】Restoration of string 亂搞

ios scanf style == pan name 題解 cst span

【CF886D】Restoration of string

題意:對於給定的一個母串,定義一個字符串是出現頻率最多的,當且僅當它在母串中出現的次數最多(可以有多個出現次數最多的,出現的位置可以重疊)。

現在給你一個字符串集合S,問你如果要求S中的所有字符串的出現頻率都是最多的,最短的母串是什麽。(如果有多個長度相同的母串,輸出字典序最小的)。

|S|<=100000

題解:容易發現出現次數最多的一定是單個字符。

那麽對於S中任意兩個相鄰的字符ab,一旦出現a後面就只能出現b。所以我們可以從a到b連一條邊。這樣最後我們得到的圖一定形如若幹條鏈。簡單判一下無解的情況,最後輸出即可。

#include <cstdio>
#include <cstring>
#include <iostream>
using namespace std;
int n,m,flag;
char s[100010];
int to[30],vis[30],from[30],used[30];
int main()
{
	memset(to,-1,sizeof(to)),memset(from,-1,sizeof(from));
	scanf("%d",&n);
	int i,j,a,b,l;
	for(i=1;i<=n;i++)
	{
		scanf("%s",s),l=strlen(s),s[l]=‘a‘-1;
		for(j=1;j<l;j++)
		{
			a=s[j-1]-‘a‘,b=s[j]-‘a‘;
			if((to[a]!=-1&&to[a]!=b)||(from[b]!=-1&&from[b]!=a))
			{
				puts("NO");
				return 0;
			}
			to[a]=b,from[b]=a,vis[b]=1;
		}
		vis[s[0]-‘a‘]=1;
	}
	for(i=0;i<26;i++)	if(vis[i]&&from[i]==-1)	for(j=i;j!=-1;j=to[j])	s[m++]=j+‘a‘,used[j]=1;
	for(i=0;i<26;i++)	if(vis[i]&&!used[i])
	{
		puts("NO");
		return 0;
	}	
	s[m]=‘\0‘,printf("%s",s);
	return 0;
}//4 mail ai lru cf

【CF886D】Restoration of string 亂搞