题意:求n个字符串的最长公共串。
思路很简单:枚举第一个字符串的不同长度子串,判断她是否为下面多有的公共子串?如果是的话,那么我们就表明找到,则比较其长度,如果比已经找到的串长,那么就替换结果串 否则按字典序比较。取字典序考前的,就可以。
#include <cstdio>
#include <iostream>
#include <cstring>
#include <string>
#include <cstdlib>
#include <algorithm>
#include <cmath>
#include <vector>
#include <set>
#include <list>
#include <queue>
#include <map>
#include <stack>
using namespace std;
#define L(i) i<<1
#define R(i) i<<1|1
#define INF 0x3f3f3f3f
#define pi acos(-1.0)
#define eps 1e-3
#define maxn 1000010
#define MOD 100000000
int len,n,cnt;
int Next[1000010];
char s[13][110],tmp[66];
void get_next()
{
int i = 0, j = -1;
Next[0] = -1;
while(i < len)
{
if(j == -1 || tmp[i] == tmp[j])
Next[++i] = ++j;
else
j = Next[j];
}
}
void kmp()
{
cnt = INF;
get_next();
for(int i = 1; i < n; i++)
{
int j = 0,k = 0,m = 0;
while(j < 60 && k < len)
{
if(k == -1 || s[i][j] == tmp[k])
j++,k++;
else
k = Next[k];
if(k > m)
m = k;
}
cnt = min(cnt,m);
}
}
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
scanf("%d",&n);
for(int i = 0; i < n; i++)
scanf("%s",s[i]);
int ans = 0;
char result[66];
for(int i = 0; i < 60; i++)
{
strcpy(tmp,s[0]+i);
len = 60 - i;
kmp();
if(cnt > ans)
{
ans = cnt;
strncpy(result,s[0]+i,ans);
result[ans] = '\0';
}
else if(cnt == ans)
{
char ss[66];
strncpy(ss,s[0]+i,ans);
ss[ans] = '\0';
if(strcmp(ss,result) < 0)
strcpy(result,ss);
}
}
if(ans >= 3)
printf("%s\n",result);
else
printf("no significant commonalities\n");
}
return 0;
}