题目链接:http://poj.org/problem?id=1226
解题思路:
枚举一个串所有子串/对应反串,与其他串匹配,求最长的 某个子串/反串 和 所有其他串 都匹配 的长度即可。
代码:
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
#define for0(i,a,b) for (int i=a;i<b;i++)
#define for1(i,a,b) for (int i=a;i<=b;i++)
char s[110][110],t1[110],t2[110];
int fail1[110],fail2[110];
int len[110];
void GETFAIL(char *s,int len,int fail[])
{
fail[0] = -1;
for (int i=0,j=-1;i<len;){
if (j==-1||s[i]==s[j]){i++;j++;fail[i] = j;}
else j = fail[j];
}
}
bool KMP(char *s,char *ss,int len,int llen,int fail[])
{
int maxj = 0;
for (int i=0,j=0;i<len;){
if (j==-1||s[i]==ss[j]){
i++;j++;
}
else j = fail[j];
if (j==llen) return true;;
}
return false;
}
int main()
{
int T;
scanf("%d",&T);
while (T--){
int n;
scanf("%d",&n);
for1(i,1,n) scanf("%s",s[i]),len[i] = strlen(s[i]);
if (n==1){printf("%d\n",len[1]);continue;}
int ans = 0;
///枚举串1所有子串和反串
for (int i=0;i<len[1];i++){
for (int j=i;j<len[1];j++){
int tot = 0;
for (int k = i;k<=j;k++){t1[tot++] = s[1][k];} t1[tot] = '\0';///获得子串
GETFAIL(t1,tot,fail1);//printf("t1=");puts(t1);
for (int k = tot-1;k>=0;k--){t2[tot-1-k] = t1[k];} t2[tot] = '\0';///获得反串
GETFAIL(t2,tot,fail2);//printf("t2=");puts(t2);
bool flag = true;
for1(k,2,n){ if (!KMP(s[k],t1,len[k],tot,fail1) && !KMP(s[k],t2,len[k],tot,fail2)) {flag = false;break;}}
if (flag) ans = max(ans,tot);
}
}
printf("%d\n",ans);
}
return 0;
}