You are given a number of case-sensitive strings of alphabetic characters, find the largest string X, such that either X, or its inverse can be found as a substring of any of the given strings.
找出最长的一个子串,所有串中都出现过它或它的逆序
扩展KMP水题
1 #include<stdio.h>
2 #include<string.h>
3 #include<iostream>
4 #include<string>
5 #include<algorithm>
6 using namespace std;
7
8 const int maxn=505;
9 int nxt[105][maxn],ext[105][maxn];
10 char s[105][maxn];
11 int len[105],ans[maxn];
12
13 void EKMP(char s[],char t[],int lens,int lent,int c){
14 int i,j,p,l,k;
15 nxt[c][0]=lent;j=0;
16 while(j+1<lent&&t[j]==t[j+1])j++;
17 nxt[c][1]=j;
18 k=1;
19 for(i=2;i<lent;i++){
20 p=nxt[c][k]+k-1;
21 l=nxt[c][i-k];
22 if(i+l<p+1)nxt[c][i]=l;
23 else{
24 j=max(0,p-i+1);
25 while(i+j<lent&&t[i+j]==t[j])j++;
26 nxt[c][i]=j;
27 k=i;
28 }
29 }
30
31 j=0;
32 while(j<lens&&j<lent&&s[j]==t[j])j++;
33 ext[c][0]=j;k=0;
34 for(i=1;i<lens;i++){
35 p=ext[c][k]+k-1;
36 l=nxt[c][i-k];
37 if(l+i<p+1)ext[c][i]=l;
38 else{
39 j=max(0,p-i+1);
40 while(i+j<lens&&j<lent&&s[i+j]==t[j])j++;
41 ext[c][i]=j;
42 k=i;
43 }
44 }
45 }
46
47 int main(){
48 int T;
49 scanf("%d",&T);
50 while(T--){
51 memset(ans,0x3f,sizeof(ans));
52 int n;
53 scanf("%d",&n);
54 for(int i=1;i<=n;++i)scanf("%s",s[i]);
55 for(int i=1;i<=n;++i)len[i]=strlen(s[i]);
56 s[1][len[1]]='#';
57 for(int i=1;i<=len[1];++i)s[1][len[1]+i]=s[1][len[1]-i];
58 s[1][len[1]+len[1]+1]=0;
59 len[1]=strlen(s[1]);
60 int maxx=0;
61 for(int i=0;i<len[1];++i){
62 for(int j=2;j<=n;++j){
63 int cnt=0;
64 EKMP(s[j],s[1]+i,len[j],len[1]-i,j);
65 for(int k=0;k<len[j];++k){
66 if(ext[j][k]>cnt)cnt=ext[j][k];
67 }
68 if(cnt<ans[i])ans[i]=cnt;
69 }
70 if(ans[i]>maxx)maxx=ans[i];
71 }
72 printf("%d
",maxx);
73 }
74 return 0;
75 }