题意:
Problem Description

女神邀请众ACdream开联欢会,显然作为ACM的佼佼者,气球是不能少的~。女神准备了三种颜色的气球,红色,黄色,绿色(交通信号灯?)
有气球还不能满足女神,女神要在气球上写字。
写什么好呢~?字符串神马的最有爱了~
女神先拿出一个字符串,然后把字符串的每一个真·前缀写到了黄色气球上面,每一个真·后缀写到了绿色气球上面,每一个真·子串写到了红色气球上面。
对于一个字符串s[1…n],真·前缀为s1…i·,真·后缀为sj…n,真·子串为si…j
于是女神就得到了好多好多的气球~
那么在同时出现在三种颜色的气球上的字符串中,最长是什么?
神马,404 not found? 找不到这样的字符串?女神很生气!那就只好输出”angry goddess”了。(不包括双引号,注意大小写,中间有一个空格)
Input

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

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

abcabcabc
aaaaaaaaa
abcabc
Sample Output

abc
aaaaaaa
angry goddess
Hint

对于样例2,由于aaaaaaaa不是真子串,因此不会出现在红色气球上面
对于样例3,由于abc是真前缀,真后缀,但不是真子串,所以找不到这样的字符串
题解:先用kmp算法得到next数组,就可以知道前i个字符前缀和后缀相同的字符串长度,先可以得到next[len]是最大可能解,然后扫描位置2到位置len-1的next数组是否能得到相同的长度next[len],说明是存在相同中缀,找不到就继续找next[next[len]],缩小长度再扫描,直到next[temp] == 0。

#include <stdio.h>
#include <string.h>
const int N = 100005;
char str[N];
int next[N], len;

void get_next() {
    int pp = -1, k = 0;
    next[0] = -1;
    while (k < len) {
        if (pp == -1 || str[pp] == str[k]) {
            k++;
            pp++;
            next[k] = pp;
        }
        else
            pp = next[pp];
    }
}

int main() {
    while (scanf("%s", str) != EOF) {
        len = strlen(str);
        get_next();
        int temp = len, res = -1;
        while (next[temp]) {
            for (int i = 1; i <= len - 1; i++)       
                if (next[i] == next[temp]) {
                    res = next[temp];
                    break;
                }
            if (res != -1)
                break;
            temp = next[temp];
        }
        if (res == -1)
            printf("angry goddess\n");
        else {
            for (int i = 0; i < res; i++)
                printf("%c", str[i]);
            printf("\n");
        }
    }
    return 0;
}