我是挑第一个字符串,枚举它的所有子串,然后那子串对剩下所有的串做KMP匹配。不过速度有点慢。后来看网上的别人写的题解,发现原来可以挑最短的一条对其他串做匹配。。。。
#include <iostream> #include <sstream> #include <algorithm> #include <vector> #include <queue> #include <stack> #include <map> #include <set> #include <bitset> #include <cstdio> #include <cstring> #include <cstdlib> #include <cmath> #include <climits> #define maxn 105 #define eps 1e-6 #define mod 10007 #define INF 99999999 #define lowbit(x) (x&(-x)) //#define lson o<<1, L, mid //#define rson o<<1 | 1, mid+1, R typedef long long LL; using namespace std; char a[maxn][maxn]; char b[maxn][maxn]; int len[maxn]; int next[maxn]; int n; void read(void) { int i, j, k; scanf("%d", &n); for(i = 1; i <= n; i++) { scanf("%s", a[i]); len[i] = strlen(a[i]); } for(i = 1; i <= n; i++) for(j = 0, k = len[i] - 1; j < len[i]; j++, k--) b[i][j] = a[i][k]; } void get(char *p, int m) { next[0] = next[1] = 0; int i, j; for(i = 1; i <= m; i++) { j = next[i]; while(j && p[i] != p[j]) j=next[j]; next[i+1] = p[i]==p[j] ? j+1 : 0; } } bool kmp(char *p, char *t, int m, int lengh) { int i, j; for(i = 0, j = 0; i <= lengh; i++) { while(j && t[i] != p[j]) j=next[j]; if(t[i] == p[j]) j++; if(j == m) return true; } return false; } void work(void) { int ans = 0, i, j, k, ok; for(i = 0; i < len[1]; i++) { for(j = i; j < len[1]; j++) { if(j - i + 1 <= ans) continue; get(a[1] + i, j - i + 1); ok = 1; for(k = 2; k <= n; k++) if(!kmp(a[1] + i, a[k], j - i + 1, len[k])) if(!kmp(a[1] + i, b[k], j - i + 1, len[k])) ok=0; //printf("%d %d %d\n", i, j, ok); if(ok) ans = j - i + 1; } } //printf("%d\n", ans); for(i = 0; i < len[1]; i++) { for(j = i; j < len[1]; j++) { if(j - i + 1 <= ans) continue; get(b[1] + i, j - i + 1); ok = 1; for(k = 2; k <= n; k++) if(!kmp(b[1] + i, a[k], j - i + 1, len[k])) if(!kmp(b[1] + i, b[k], j - i + 1, len[k])) ok=0; if(ok) ans = j - i + 1; } } printf("%d\n", ans); } int main(void) { int _; while(scanf("%d", &_)!=EOF) { while(_--){ read(); work(); } } return 0; }