题目链接: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 }