[ACdream] 女神教你字符串——三个气球

Problem Description

女神邀请众ACdream开联欢会,显然作为ACM的佼佼者,气球是不能少的~。女神准备了三种颜色的气球,红色,黄色,绿色(交通信号灯?)

有气球还不能满足女神,女神要在气球上写字。

写什么好呢~?字符串神马的最有爱了~

女神先拿出一个字符串,然后把字符串的每一个真·前缀写到了黄色气球上面,每一个真·后缀写到了绿色气球上面,每一个真·子串写到了红色气球上面。

对于一个字符串s[1...n],真·前缀为s[1...i](1<=i<n)·,真·后缀为s[j...n](1<j<=n),真·子串为s[i...j](1<i<=j<n)

于是女神就得到了好多好多的气球~

那么在同时出现在三种颜色的气球上的字符串中,最长是什么?

神马,404 not found? 找不到这样的字符串?女神很生气!那就只好输出"angry goddess"了。(不包括双引号,注意大小写,中间有一个空格)

Input

多组数据,每组数据一行字符串,长度不超过100000,

Output

对于每组数据,输出一个字符串

Sample Input

abcabcabc
aaaaaaaaa
abcabc

Sample Output

abc
aaaaaaa
angry goddess

解题思路:
其实这题就是求,一个字符串中有没有三个相同的子串,这三个字串必须一个是 s1[0..i<n-1],s2[0<i....j<n-1],s3[0<j....n-1],刚开始的做法是直接用kmp算法一个一个搜符合
条件的,但是由于数据很大超时,最后想到了next数组的原理正好他的值就是前后缀相等的个数,只要再找出与中间的next[i]相等的就符合条件了,当然这一个也是最大的串,首先将len=next
[strlen(ab)],从最后往前找,找到符合条件的就结束,可以输出结果,找不到就就len=next[len],不然会超时!如果没有找到一个,那么这个结束条件是len=-1或者=0

AC代码:

#include <iostream>
#include <algorithm>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
using namespace std;
char ab[100005];
char nb[100005];
int next[100005];
void getNext(char *nb)
{
    int j=0,k=-1;
    next[0]=-1;
    while(j<strlen(nb))
    {
        if(k==-1||nb[j]==nb[k])
        {
            j++;  k++;
            next[j]=k;
        }
        else  k=next[k];
    }
}
int main()
{
    int i,temp,max1;
    while(gets(ab))
    {
        temp=0;max1=0;
        strcpy(nb,ab);
        getNext(nb);
        int len=next[strlen(ab)];
        while(len!=0&&len!=-1)
        {
             for(i=2;i<strlen(ab)-1;i++)
             {
                if(len==next[i])
                {
                    temp=1;break;
                }
            }
            if(temp) break;
            len=next[len];
        }
        if(!temp) printf("angry goddess");
        for(i=0;i<len;i++)
        {
            printf("%c",ab[i]);
        }
        cout<<endl;
    }
    return 0;
}
原文地址:https://www.cnblogs.com/gaojupeng/p/4484969.html