这道题我们发现每个串的长度只有60

所以对于第一个串(或者选一个你喜欢的)枚举子串分别与其他串KMP匹配

注意长度相等时字典序最小&&长度<3时 no significant commonalities

 1 #include<cstdio>
 2 #include<cstring>
 3 using namespace std;
 4 const int len=60;
 5 int Q,n,tmplen,lenth,pre[65],m[65];
 6 char s[12][65],ans[65],tmp[65];
 7 int dic(){
 8     if (tmplen!=lenth) return 0;
 9     for (int i=1;i<=tmplen;i++){
10         if (tmp[i]<ans[i]) return 1;
11         if (tmp[i]>ans[i]) return 0;
12     }
13     return 0;
14 }
15 void KMP(int l,int r){
16     int p=l,q=1;
17     while (p<=r){
18         tmp[q]=s[1][p];
19         p++;q++;
20     }
21     tmplen=r-l+1;
22     pre[1]=0;
23     for (int i=2;i<=tmplen;i++){
24         int j=pre[i-1];
25         while (j&&tmp[j+1]!=tmp[i]) j=pre[j];
26         if (tmp[j+1]==tmp[i]) j++;
27         pre[i]=j;        
28     }
29     int k=1,judge;
30     while (k<n){
31         k++;judge=m[1]=0;
32         for (int i=1;i<=len;i++){
33             int j=m[i-1];
34             while (j&&tmp[j+1]!=s[k][i]) j=pre[j];
35             if (tmp[j+1]==s[k][i]) j++;
36             m[i]=j;
37             if (j==tmplen) {
38                 judge=1;break;
39             }
40         }
41         if (!judge) return;
42     }
43     if (lenth<tmplen||dic()){
44         int p=l,q=1;
45         for (int i=1;i<=tmplen;i++)
46             ans[i]=tmp[i];
47         lenth=tmplen;
48     }
49 }
50 int main(){
51     scanf("%d",&Q);
52     while (Q--){
53         memset(pre,0,sizeof(pre)); 
54         lenth=0; 
55         scanf("%d",&n);
56         for (int i=1;i<=n;i++)
57             scanf("%s",s[i]+1);
58         for (int i=1;i<=len;i++){
59             for (int j=i;j<=len;j++) KMP(i,j);
60         }
61         if (lenth<3) 
62             printf("no significant commonalities");
63         else 
64             for (int i=1;i<=lenth;i++){
65                 printf("%c",ans[i]);
66             }
67         printf("\n");
68     }
69     return 0;
70 }
STD

 

posted on 2016-10-06 11:31  Absolutezero  阅读(224)  评论(0编辑  收藏  举报