寒假训练--训练赛2--Good Luck!

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;
}


你可能感兴趣的:(寒假训练--训练赛2--Good Luck!)