The Dominator of Strings
Time Limit: 3000/3000 MS (Java/Others) Memory Limit: 65535/32768 K (Java/Others)Total Submission(s): 381 Accepted Submission(s): 97
Problem Description
Here you have a set of strings. A dominator is a string of the set dominating all strings else. The string
S
is dominated by
T
if
S
is a substring of
T
.
Input
The input contains several test cases and the first line provides the total number of cases.
For each test case, the first line contains an integer N indicating the size of the set.
Each of the following N lines describes a string of the set in lowercase.
The total length of strings in each case has the limit of 100000 .
The limit is 30MB for the input file.
For each test case, the first line contains an integer N indicating the size of the set.
Each of the following N lines describes a string of the set in lowercase.
The total length of strings in each case has the limit of 100000 .
The limit is 30MB for the input file.
Output
For each test case, output a dominator if exist, or No if not.
Sample Input
3 10 you better worse richer poorer sickness health death faithfulness youbemyweddedwifebetterworsericherpoorersicknesshealthtilldeathdouspartandpledgeyoumyfaithfulness 5 abc cde abcde abcde bcde 3 aaaaa aaaab aaaac
赛时调了一下午AC自动机,一直超时。过后问ACfun群里,kmp就能过,啊啊啊,想骂人了。我一直以为kmp更超时,没敢用。
赛后用kmp的模板直接跑了一遍就过了。还是太弱了,技巧性的东西或者脑袋都不够灵活。5个小时需要灵动思路啊
【代码】:
#include <stdio.h>
#include <string.h>
char S[1200010];
char *t[1100010],*s;
int f[1202020];
void getfail(char p[],int f[]) //字符串p自我匹配
{
int len=strlen(p);
f[0]=f[1]=0;
for(int i=1;i<len;i++)
{
int j=f[i];
while(j&&p[i]!=p[j])
j=f[j];
if(p[i]==p[j])
f[i+1]=j+1;//多匹配到了一个字符
else
f[i+1]=0;//该字符配不上
}
}
int find(char* T, char*P, int*f)//p去匹配字符串T
{
int n = strlen(T), m = strlen(P);
getfail(P, f); //得出部分匹配表
int j = 0; //短串的下标
for(int i = 0; i < n; i++) //长串下标
{
while(j && P[j] != T[i])//突然失配了
{
j = f[j]; //j往回退,直到0或者上一个字符相等的位置
}
if(P[j] == T[i])
{
j++; //匹配了一个字符,j++
}
if(j == m) //短串匹配到头了
{
return 1;//i - m + 1;//返回成功匹配的起点字符位置
}
}
return -1;
}
int main()
{
int T,n;
scanf("%d",&T);
while(T--)
{
scanf("%d",&n);
int maxlen=0;
int p=1;//记录最长串
s=S;
for(int i=1;i<=n;i++)
{
scanf("%s",s);
t[i]=s;
if(strlen(s)>maxlen){
maxlen=strlen(s);
p=i;
}
s+=strlen(s)+2;
}
int ans=0;
for(int i=1;i<=n;i++)
{
if(find(t[p],t[i],f)==1)
ans++;
else break;
}
if(ans==n)
{
printf("%s\n",t[p]);
}
else puts("No");
}
return 0;
}