题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5510
思路:
一开始直接用KMP莽了发,超时了,后面发现如果前面的字符串被后面的字符串包含,那么我们就不需要用前面的字符串去比较了,把他标记掉就好了。
实现代码:
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdio>
using namespace std;
char s[][];
int vis[];
int next1[];
int slen,tlen;
void get_next(char *mat)
{
int j,k;
tlen=strlen(mat);
j=;k=-;next1[]=-;
while(j<tlen)
{
if(k==-||mat[j]==mat[k])
next1[++j]=++k;
else
k=next1[k];
}
}
int kmp_pos(char *str,char *mat)
{
int i=,j=;
slen=strlen(str);
get_next(mat);
while(i<slen&&j<tlen)
{
if(j==-||str[i]==mat[j])
{
i++;j++;
}
else
j=next1[j];
}
if(j==tlen)
return i-tlen;
return -;
}
int main()
{
int tt,n;
int ttt=;
scanf("%d",&tt);
while(tt--)
{
ttt++;
int sum=-;
scanf("%d",&n);
for(int i=;i<=n;i++)
{
scanf("%s",s[i]);
vis[i] = ;
}
int flag=;
int st = ;
for(int i = ;i <= n;i ++){
int ans=kmp_pos(s[i],s[i-]);
if(ans != -)
vis[i-] = ;
}
for(int i=n;i>=;i--)
{
flag=;
for(int j=i-;j>=;j--)
{
if(vis[j]==) continue;
int ans=kmp_pos(s[i],s[j]);
if(ans==-)
{
flag=;break;
}
}
if(flag==)
{
sum=i;break;
}
}
printf("Case #%d: ",ttt);
printf("%d\n",sum);
}
}