Good Luck!
Time Limit: 1000MS Memory limit: 65536K
题目描述
我们都知道,前缀就是一个单词的前几个字母(长度小于单词长度);后缀就是一个单词的后几个字母(长度小于单词长度)。例如:Hello,{H,He,Hel,Hell}都是Hello的前缀,{ello,llo,lo,o}都是Hello的后缀。现在,给你一个字符串String,你的任务是找出一个字串s,s既是String的前缀,又是String的后缀,并且s也出现在String的中间部分(既不是前缀,也不是后缀),s的长度越长越好。
输入
输入一个N,接下来N行,每行一个字符串String,String长度len( 1 <= len <= 1000000)。
输出
输出只有一行,如果有符合条件的s,输出长度最长的s,如果没有,输出“Bad Luck!”(不含引号)。
示例输入
3 abcabcabcabcabc papapapap aaabaaaabab
示例输出
abcabcabc papap Bad Luck!
提示
KMP的题目,首先判断next[l],如果它是0的话 就没有相同前缀与后缀,如果不为0 那么现在next数组里面匹配,如果可以找到与next[l] 相同的数,即证明有中间的与前缀相同,输出。 如果没有 判断next[ next[l] ] ,判断原本的前缀有没有相同的,如果有,减小前缀,可以找到结果
来源
GLSilence
示例程序
#include <stdio.h>
#include <string.h>
char str[1000100] ;
int next[1000100] ;
void getnext()
{
int j = 0 , k = -1 , l = strlen(str);
next[0] = -1 ;
while(j <= l )
{
if(k==-1 || str[j] == str[k])
{
j++ ;
k++;
next[j] = k;
}
else
k = next[k] ;
}
/* for(int i=0;i<=l;i++)printf("%d ",next[i]);
printf("\n");*/
}
int main()
{
//freopen("data1.in","r",stdin);
int i , n , l , j , flag ;
scanf("%d", &n);
for(i = 0 ; i < n ; i++)
{
flag = 0 ;
scanf("%s", str);
l = strlen(str);
getnext();
for(j = 0 ; j <= l ; j++)
printf("*%d %d", j , next[j]);
printf("\n");
if(next[l]==0||next[l]==-1)
{
printf("Bad Luck!\n");
continue;
}
for(i = 1 ; i < l ; i++)
if(next[i]==next[l])
{
flag = 1;
break;
}
if(flag)
{
str[ next[l] ] = '\0' ;
printf("%s\n", str);
}
else if(next[ next[l] ]>0)
{
str[next[next[l] ]] = '\0';
printf("%s\n", str);
}
else
printf("Bad Luck!\n");
}
return 0;
}