传送门:点击打开链接
题图没有半点毛关系。
题意:给出n个字符串,求出最大的i串(是i最大不是i串长度最大)使得存在j串不是i串的子串。
做法是用kmp来求是不是字串,再减枝,求出一个串是别的子串就不用再管它了,以后可以遍历比它长的串
代码如下:
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<cstring>
using namespace std;
#define N 510
#define inf 2000000000000000ll
struct rng{
char a[2010];
int len,Next[2010];
}t[N];
int vis[N];
void getnext(int cnt)
{
int i,j;
i=0,j=-1;
t[cnt].Next[0]=-1;
while(i<t[cnt].len)
{
if(j==-1||t[cnt].a[i]==t[cnt].a[j])
{
j++,i++;
t[cnt].Next[i]=j;
}
else j=t[cnt].Next[j];
}
return ;
}
bool find(int x,int y){
int i=0,j=0;
while(i<t[x].len){
if(j==-1||t[x].a[i]==t[y].a[j]){
j++;
i++;
}
else j=t[y].Next[j];
if(j==t[y].len){
return 0;
}
}
return 1;
}
int main(){
int T,i,j,n,m,k,kase=0;
scanf("%d",&T);
while(T--){
scanf("%d",&n);
int flag1=0;
memset(vis,0,sizeof(vis));
for(i=1;i<=n;i++)
{
scanf("%s",&t[i].a);
t[i].len=strlen(t[i].a);
getnext(i);
for(j=1;j<=i-1;j++){
if(vis[j]) continue;
if(find(i,j)==0) vis[j]=1;
else flag1=i;
}
}
printf("Case #%d: ",++kase);
if(flag1)
printf("%d\n",flag1);
else
printf("-1\n");
}
return 0;
}