給出幾個由小寫字母構成的單詞,求它們最長的公共子串的長度。
任務:
l 讀入單詞
l 計算最長公共子串的長度
l 輸出結果
其實這題我沒A由於權限號密碼忘了 可是在COGS過了那就發一下吧。。 已ACspa
感受很zz啊,和單個串有什麼區別。code
那就直接把除了第一個串以外的SAM建出來而後枚舉第一個串暴力匹配求最小就行了blog
1Ahhhip
update:get
??爲何網上的題解都和我不同??string
這題好像只建一個SAM就好了??!!感受本身好菜啊。。。it
#include<cstdio> #include<cstring> #include<algorithm> using namespace std; const int MAXN = 2001 * 2, INF = 1e9 + 10; inline int read() { char c = getchar(); int x = 0, f = 1; while(c < '0' || c > '9') {if(c == '-') f = -1; c = getchar();} while(c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar(); return x * f; } struct SuffixAut { int fa[MAXN], len[MAXN], ch[MAXN][27], tot, last, root, ans, cur; SuffixAut() { cur = tot = last = root = 1; ans = 0;} void insert(int x) { int now = ++tot, pre = last; last = now; len[now] = len[pre] + 1; for(; pre && !ch[pre][x]; pre = fa[pre]) ch[pre][x] = now; if(!pre) fa[now] = root; else { int q = ch[pre][x]; if(len[q] == len[pre] + 1) fa[now] = q; else { int nows = ++tot; memcpy(ch[nows], ch[q], sizeof(ch[q])); fa[nows] = fa[q]; fa[q] = fa[now] = nows; len[nows] = len[pre] + 1; for(; pre && ch[pre][x] == q; pre = fa[pre]) ch[pre][x] = nows; } } } int work(int x) { if(ch[cur][x]) {cur = ch[cur][x]; ans++; return ans;} for(; cur && !ch[cur][x]; cur = fa[cur]); if(!cur) cur = root, ans = 0; else ans = len[cur] + 1, cur = ch[cur][x]; return ans; } }Suf[6]; char s[6][MAXN]; int N[6]; int main() { #ifdef WIN32 freopen("a.in", "r", stdin); #else freopen("pow.in", "r", stdin); freopen("pow.out", "w", stdout); #endif int num = read(); for(int i = 1; i <= num; i++) scanf("%s", s[i] + 1), N[i] = strlen(s[i] + 1); for(int i = 2; i <= num; i++) for(int j = 1; j <= N[i]; j++) Suf[i].insert(s[i][j] - 'a'); int out = 0; for(int i = 1; i <= N[1]; i++) { int ans = INF; for(int j = 2; j <= num; j++) ans = min(ans, Suf[j].work(s[1][i] - 'a')); out = max(out, ans); } printf("%d", out); return 0; }