​点击打开链接​

二分长度 然后枚举第一个串的所有子串 用kmp判断其是否为其他所有串的子串

 

#include <bits/stdc++.h>
using namespace std;
const int maxn=1e2+10;

char ch[maxn][maxn];
int len[maxn],nxtt[maxn];
char t[maxn];
int n;

void kmp(char *t,int lt)
{
int i,j;
nxtt[0]=-1;
i=0,j=-1;
while(i<lt){
if(j==-1||t[i]==t[j]){
i++,j++;
nxtt[i]=j;
}
else j=nxtt[j];
}
}

bool solve(char *s,int ls,char *t,int lt)
{
int i,j;
i=0,j=0;
while(i<ls){
if(j==-1||s[i]==t[j]){
i++,j++;
if(j==lt) return 1;
}
else j=nxtt[j];
}
return 0;
}

bool judge(int val)
{
int book[maxn];
int i,j,flag;
for(i=0;i+val-1<len[1];i++){
memset(book,0,sizeof(book));
for(j=i;j<=i+val-1;j++){
t[j-i]=ch[1][j];
}
t[val]='\0';
kmp(t,val);
for(j=1;j<=n;j++){
book[j]|=solve(ch[j],len[j],t,val);
}
for(j=0;j<val/2;j++){
swap(t[j],t[val-1-j]);
}
kmp(t,val);
for(j=1;j<=n;j++){
book[j]|=solve(ch[j],len[j],t,val);
}
for(j=1;j<=n;j++){
if(!book[j]) break;
}
if(j==n+1) return 1;
}
return 0;
}

int main()
{
int t,i,l,r,m,ans;
scanf("%d",&t);
while(t--){
scanf("%d",&n);
for(i=1;i<=n;i++){
scanf("%s",ch[i]);
len[i]=strlen(ch[i]);
}
l=1,r=len[1],ans=0;
while(l<=r){
m=(l+r)/2;
if(judge(m)) l=m+1,ans=m;
else r=m-1;
}
printf("%d\n",ans);
}
return 0;
}