1. 程式人生 > >18.12.20 DSA 最長公共子串

18.12.20 DSA 最長公共子串

描述

給出n個由小寫字母組成的字串,求一個最長的字串,它同時是這n個字串的子串。

輸入

第一行是一個整數n(1<=n<=5),表示輸入字串的個數。
接下來n行每行為一個由小寫字母構成的字串,每個字串的長度至少為1,最長不超過2000。輸出輸出一行整數,為最長公共子串的長度。

樣例輸入

3
abcb
bca
acbc

樣例輸出

2

提示

資料範圍
對於40%的資料,每個字串的長度不超過200。來源POI 2000

 1 #include <iostream>
 2 #include <string.h>
 3 #include <algorithm>
 4
#include <stack> 5 #include <string> 6 #include <math.h> 7 #include <queue> 8 #include <stdio.h> 9 #include <string.h> 10 #include <set> 11 #include <vector> 12 #include <fstream> 13 #define maxn 4005 14 #define inf 999999 15 #define
cha 127 16 #define eps 1e-6 17 using namespace std; 18 19 int Next[maxn]; 20 int ans = 0, n,size0; 21 string line[6], cb; 22 23 int findnext(int s) { 24 memset(Next, 0, sizeof(Next)); 25 int i = s, k = -1+s, m = cb.length(); 26 int Max = 0; 27 Next[i] = s-1; 28 while (i < m-1
) { 29 while (k >= s && cb[i] != cb[k]) 30 k = Next[k]; 31 i++, k++; 32 Next[i] = k; 33 if(i-k+s+1>=size0) 34 Max = max(Max, k - s); 35 } 36 return Max; 37 } 38 39 void init() { 40 scanf("%d", &n); 41 for (int i = 1; i <= n; i++) 42 cin >> line[i]; 43 size0 = line[1].length(); 44 for (int i = 0; i < size0; i++) { 45 int min0 = inf; 46 for (int j = 2; j <= n; j++) { 47 cb = line[1] +'-'+ line[j]+'-'; 48 int tmp = findnext(i); 49 if (tmp <= ans) 50 { 51 min0 = 0; 52 break; 53 } 54 min0 = min(min0, tmp); 55 } 56 ans = max(min0, ans); 57 } 58 printf("%d\n", ans); 59 } 60 61 int main() { 62 init(); 63 return 0; 64 }
View Code

超級容易WA,滿滿的惡意……

WA點:

1)next陣列要開兩倍大小,不然RE

2)兩個串拼起來的時候中間要有分隔符,不然算到的值很可能錯誤

3)findnext函式要仔細寫,特別是終止迴圈條件那個數

4)

4
aaaa
sjdiwaaaa
aaaa
sjdiaaawdeji

4
aaaa
aaaaa
aaaaaa
aaa