攒了一堆题目木有写题解嘤,后天就比赛了求人品><。这一题开始用KMP+N^2暴力直接TLE了,后来得知应该优化一下:因为字符串是从短到长排列且i从前往后遍历,对于a, b, c (a<b<c), if a in b: if a not in c, then b must not in c, 只需判断b与c的关系(因为只要找到一个非子串)。if a in c, a对于结果就没有意义了,只需关注b是否in c。
#include<iostream>
#include<stdio.h>
#include<cstdio>
#include<string>
#include<cmath>
#include<stdlib.h>
#include<algorithm>
#include<string.h>
#include<cstring>
#include<vector>
#include<queue>
#include<map>
using namespace std;
//hdu 5510
const int maxn=510;
const int maxz=2010;
int n;
int t;
char str[maxn][maxz];
//string str[maxn]; 用string会TLE
int ans;
int Next[maxn][maxz];
int vis[maxn];
//void kmp_pre(string x,int idx)
void kmp_pre(char x[],int idx)
{
//memset(Next,0,sizeof(Next));
int i=0;
Next[idx][0]=-1;
int j=-1;
int lenx=strlen(x);
while(i<lenx)
{
while(-1!=j && x[i]!=x[j]) j=Next[idx][j];
if(x[++i]==x[++j]) Next[idx][i]=Next[idx][j];
else Next[idx][i]=j;
}
}
int kmp_count(char x[],char y[],int idx)
{
int i=0;
int j=0;
int ans=0;
//kmp_pre(x,idx);
int leny=strlen(y);
int lenx=strlen(x);
while(i<leny)//循环中计算strlrn(y)会TLE
{
while(-1!=j && y[i]!=x[j]) j=Next[idx][j];
i++;
j++;
if(j>=lenx)
{
ans++;
j=Next[idx][j];
}
}
return ans;
}
int main()
{
freopen("input.txt","r",stdin);
scanf("%d",&t);
for(int ca=1;ca<=t;ca++)
{
scanf("%d",&n);
ans=-1;
memset(Next,0,sizeof(Next));
memset(vis,0,sizeof(vis));
memset(str,0,sizeof(str));
for(int i=1;i<=n;i++)
{
//cin>>str[i];
scanf("%s",str[i]);
kmp_pre(str[i],i);
}
for(int i=1;i<=n;i++)
{
bool flg=false;
for(int j=1;j<i;j++)
{
if(vis[j]==1) continue;
//kmp_pre(str[j]);
//cout<<str[i]<<" "<<str[j]<<" "<<kmp_count(str[j],str[i])<<endl;
if(kmp_count(str[j],str[i],j)==0)
{
ans=i;
break;
}
else
{
vis[j]=1;
}
}
}
// for(int j=1;j<=n;j++)
// {
// //bool flg=false;
// kmp_pre(str[j]);
// for(int i=n;i>j;i--)
// {
// if(i<ans) break;
// if(kmp_count(str[j],str[i])==0)
// {
// //flg=true;
// ans=max(ans,i);
// break;
// }
// else
// {
// continue;
// }
// }
if(flg==true)
{
break;
}
// }
// for(int i=2;i<=n;i++)
// {
// kmp_pre(str[i-1]);//pattern: str[i-1]
// if(kmp_count(str[i-1],str[i])==0)
// {
// vis[i]=1;
// ans=max(ans,i);
// }
// else
// {
// if(vis[i-1]==1)
// {
// ans=max(ans,i);
// }
// }
// }
printf("Case #%d: %d\n",ca,ans);
}
}