题目链接在这:http://acm.hdu.edu.cn/showproblem.php?pid=1238
这个题目用扩展kmp可以轻易解决。
用第一个串的所有后缀去和剩下的串匹配,求出此后缀对于其他串的最小的公共长度,然后求所以后缀的最大的哪一个,记得翻转一下就行。
下面代码(码风有点丑)
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<iostream>
#include<string>
using namespace std;
const int maxn = 1e6 + 10;
char s[100][110];
int exnext[200];
int exend[200];
void get_next(char *t)
{
int n = strlen(t);
exnext[0] = n;
int p = 0, a = 0;
for(int i = 1; i < n; i++)
{
if(i >= p || i + exnext[i - a] >= p)
{
if(i >= p)
p = i;
while(p < n && t[p] == t[p - i])
p++;
a = i;
exnext[i] = p - i;
}
else
exnext[i] = exnext[i - a];
}
//printf("sdasdasda\n");
}
void exkmp(char *s, char * t)
{
int m = strlen(t);
int n = strlen(s);
get_next(t);
int p = 0, a = 0;
for(int i = 0; i < n; i++)
{
if(i >= p || exnext[i - a] + i >= p)
{
if(i >= p)
p = i;
while(p - i < m && p < n && s[p] == t[p - i])
p++;
a = i;
exend[i] = p - i;
}
else
exend[i] = exend[i - a];
}
}
int main()
{
int t;
scanf("%d", &t);
while(t--)
{
int n;
scanf("%d", &n);
for(int i = 0; i < n; i++)
{
scanf("%s", s[i]);
}
int len = strlen(s[0]);
int ans = -1;
for(int i = 0; i < len; i++)
{
int tans = 0x3f3f3f3f;
for(int j = 1; j < n; j++)
{
int mc = -1;
exkmp(s[j], s[0] + i);
int len1 = strlen(s[j]);
for(int k = 0; k < len1; k++)
mc = max(mc, exend[k]);
reverse(s[j], s[j] + len1);
//len1 = strlen(s[j]);
exkmp(s[j], s[0] + i);
for(int k = 0; k < len1; k++)
mc = max(mc, exend[k]);
tans = min(mc, tans);
}
ans = max(tans, ans);
//printf("%d\n", ans);
}
printf("%d\n", ans);
}
return 0;
}
``