kuangbin专题16I(kmp)

题目链接: https://vjudge.net/contest/70325#problem/I

 

题意: 求多个字符串的最长公共子串, 有多个则输出字典序最小的.

 

思路: 这里的字符串长度固定为 60, 可以枚举其中一个字符串的所有子串, 然后拿这个子串去和其他字符串匹配就好了. 不过如果不用 kmp 的话需要 O(N^5) 的时间复杂度, 因该会 tle.

 

代码:

 1 #include <iostream>
 2 #include <stdio.h>
 3 #include <string.h>
 4 using namespace std;
 5 
 6 const int MAXN = 1e2;
 7 int len, nxt[MAXN];
 8 char s[MAXN], sol[MAXN], str[12][MAXN];
 9 
10 void get_nxt(void){
11     memset(nxt, 0, sizeof(nxt));
12     for(int i = 1; i < len; i++){
13         int j = nxt[i];
14         while(j && s[i] != s[j]){
15             j = nxt[j];
16         }
17         nxt[i + 1] = j + (s[i] == s[j]);
18     }
19 }
20 
21 bool kmp(char *gel){
22     for(int i = 0, j = 0; i < strlen(gel); i++){
23         while(j && gel[i] != s[j]){
24             j = nxt[j];
25         }
26         if(gel[i] == s[j]) j++;
27         if(j >= len) return true;
28     }
29     return false;
30 }
31 
32 int main(void){
33     int t, n;
34     scanf("%d", &t);
35     while(t--){
36         int cnt = 0;
37         scanf("%d", &n);
38         for(int i = 0; i < n; i++){
39             scanf("%s", str[i]);
40         }
41         for(int i = 0; i < 58; i++){
42             len = 0;
43             bool flag = true;
44             s[len++] = str[0][i];
45             s[len++] = str[0][i + 1];
46             for(int j = i + 2; j < 60; j++){
47                 s[len++] = str[0][j];
48                 s[len] = '\0';
49                 get_nxt();
50                 for(int k = 1; k < n; k++){
51                     flag = kmp(str[k]);
52                     if(!flag) break;
53                 }
54                 if(!flag) break;
55                 else{
56                     if(j - i + 1 > cnt){
57                         cnt = j - i + 1;
58                         strcpy(sol, s);
59                     }else if(j - i + 1 == cnt){
60                         if(strcmp(sol, s) > 0) strcpy(sol, s);
61                     }
62                 }
63             }
64         }
65         if(cnt < 3) puts("no significant commonalities");
66         else printf("%s\n", sol);
67     }
68     return 0;
69 }
View Code

 

posted @ 2017-08-10 21:29  geloutingyu  阅读(241)  评论(0编辑  收藏  举报