题目链接:http://codeforces.com/problemset/problem/126/B

大意:给一个字符串,问最长的既是前缀又是后缀又是中缀(这里指在内部出现)的子串。

我自己的做法是用KMP的next数组,对所有既是前缀又是中缀的位置计数,再从next[n]开始走next,也即枚举所有既是前缀又是后缀的子串,看cnt[i]是否大于0,如果大于0则说明作为中缀出现过(也即有大于i的某个位置的next为i)

 1 #include <iostream>
 2 #include <vector>
 3 #include <algorithm>
 4 #include <string>
 5 #include <string.h>
 6 #include <stdio.h>
 7 #include <math.h>
 8 #include <stdlib.h>
 9 #include <queue>
10 #include <stack>
11 #include <map>
12 #include <set>
13 
14 using namespace std;
15 
16 const int N=1e6+12345;
17 char s[N];
18 int next[N];
19 int cnt[N];
20 void getNext(char *word,int n=0){
21     n=(n==0)?strlen(word):n;
22     memset(next,0,sizeof(next));
23     int i,j;
24     for (i=1;i<n;i++){
25         j=i;
26         while (j){
27             j=next[j];
28             if (word[i]==word[j]){
29                 next[i+1]=j+1;
30                 break;
31             }
32         }
33     }
34 }
35 int main () {
36     scanf("%s",s);
37     int n=strlen(s);
38     getNext(s,n);
39     for (int i=2;i<n;i++)
40         cnt[next[i]]++;
41     if (next[n]==0)
42         puts("Just a legend");
43     else {
44         for (int i=next[n];i;i=next[i]) {
45             if (cnt[i]) {
46                 for (int j=0;j<i;j++)
47                     printf("%c",s[j]);
48                 puts("");
49                 return 0;
50             }
51         }
52         puts("Just a legend");
53     }
54     return 0;
55 }
View Code

相关文章: