思路:思维定势想到用后缀数组,结果行不通。其实枚举第一个字符串的子串作为模式串,然后对后面n-1个字符串进行kmp匹配,这样的复杂度为O(L^3)
- #include <iostream>
- #include <string>
- using namespace std;
- const int N = 70, M = 15;
- int ls, lp, pre[N], len;
- char str[M][N], s2[N], ans[N];
- void prefix(char *p)
- {
- int i, k;
- memset(pre, 0, sizeof(pre));
- pre[1] = 0;
- k = 0;
- for(i = 2; i <= lp; i++)
- {
- while(k > 0 && p[k+1] != p[i]) k = pre[k];
- if(p[k+1] == p[i]) k++;
- pre[i] = k;
- }
- }
- bool kmp(char *p, char *s)
- {
- int i, k, cnt = 0;
- k = 0;
- for(i = 1; i <= ls; i++)
- {
- while(k > 0 && p[k+1] != s[i]) k = pre[k];
- if(p[k+1] == s[i]) k++;
- if(k == lp)
- {
- // cnt++;
- // k = pre[k];
- return true;
- }
- }
- return false; // also cnt
- }
- int main()
- {
- int t, n, i, j;
- scanf("%d/n", &t);
- while(t--)
- {
- scanf("%d", &n);
- for(i = 0; i < n; i++) scanf("%s", str[i]+1);
- len = 0;
- strcpy(ans, "no significant commonalities");
- for(lp = 60; lp >= 3; lp--)
- {
- for(i = 1; i+lp-1 <= 60; i++)
- {
- prefix(str[0]+i-1);
- ls = 60;
- for(j = 1; j < n; j++)
- {
- if(!kmp(str[0]+i-1, str[j])) break;
- }
- if(j >= n && lp >= len)
- {
- strncpy(s2, str[0]+i, lp);
- s2[lp] = 0;
- if(lp>len || lp==len && strcmp(s2, ans)<0)
- {
- strcpy(ans, s2);
- }
- }
- }
- if(strcmp(ans,"no significant commonalities")!=0)break;
- }
- puts(ans);
- }
- return 0;
- }