题意:给定 n 个字符串,求最大子串,使得它是 n 个字符串的子串。(若有多种答案,输出字典序最小的)
分析:每个字符串长度不超过200,则可以暴力枚举子串 然后 KMP。
代码:
#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;
const int N = 205;
int n;
char a[4005][N],b[N],ans[N];
int nxt[N],ok,rt;
int cnt[4005];
void GetNext(char s[],int nxt[],int m)
{
nxt[0]=-1;
int j=0,k=-1;
while(j<m)
{
if(k==-1||s[j]==s[k])
{
++j;
++k;
nxt[j]=k;
}
else
{
k=nxt[k];
}
}
}
bool kmp(char k[],char b[],int nxt[],int len)
{
int m=strlen(k);
int i=0,j=0;
while(i<m)
{
if(j==-1||k[i]==b[j])
{
i++;j++;
}
else
{
j=nxt[j];
}
if(j==len) return true;
}
return false;
}
bool cmp(char a[],char b[],int len)
{
for(int i=0;i<len;i++)
{
if(a[i]<b[i]) return true;
if(a[i]>b[i]) return false;
}
return false;
}
int main()
{
while(~scanf("%d",&n))
{
ans[0]='z'+1; ans[1]='\0'; rt=0;
if(n==0) break;
for(int i=0;i<n;i++) scanf("%s",a[i]),cnt[i]=strlen(a[i]);
for(int len=cnt[0];len>0;len--)
{
for(int bg=0;bg<cnt[0]-len+1;bg++)
{
for(int i=0;i<len;i++)
{
b[i]=a[0][i+bg]; // 截取的 子串
}
b[len]='\0';
if(!cmp(b,ans,len)) continue;
//cout<<b<<endl;
GetNext(b,nxt,len);
ok=1;
for(int i=1;i<n;i++)
{
if(len<=cnt[i]&&kmp(a[i],b,nxt,len));
else
{
ok=0;
break;
}
}
if(ok)
{
rt=1;
for(int i=0;i<len;i++) ans[i]=b[i];
ans[len]='\0';
}
}
if(rt)
{
ok=-1;
printf("%s\n",ans);
break;
}
}
if(ok!=-1)
{
puts("IDENTITY LOST");
}
}
return 0;
}