Accept: 61 Submit: 252
Time Limit: 3000 mSec Memory Limit : 65536 KB
Problem Description
问题很简单,给你一个字符串s,问s的子串中不包含s1,s2...sn的最长串有多长。
Input
输入包含多组数据。第一行为字符串s,字符串s的长度1到10^6次方,第二行是字符串s不能包含的子串个数n,n<=1000。接下来n行字符串,长度不大于100。
字符串由小写的英文字符组成。
Output
最长子串的长度
Sample Input
lgcstraightlalongahisnstreet
5
str
long
tree
biginteger
ellipse
Sample Output
12
Source
福州大学第十届程序设计竞赛
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
#define N 1000005
struct node
{
int x,y;
}a[N/10];
int k,next[200];
char str[N],s[200];
bool cmp(node a,node b)
{
return a.x<b.x;
}
int min(int a,int b)
{
return a<b?a:b;
}
void NEXT(char *s,int n)
{
int i,j;
j=-1;
next[0]=-1; i=0;
while(i<n)
{
if(j==-1||s[i]==s[j])
{
i++;j++;
next[i]=j;
}
else
j=next[j];
}
}
void kmp(char *s,char *str)
{
int i,j,n1,n2,p;
i=0;j=0;
n1=strlen(str);
n2=strlen(s);
while(i<n1)
{
if(j==-1||str[i]==s[j])
{
i++; j++;
}
else
j=next[j];
if(j==n2)
{
//printf("i-1=%d\n",i-1);
int len=i-n2;
for(p=0;p<k;p++)
{
if(a[p].x==len)
break;
}
if(p<k)
a[p].y=min(a[p].y,n2);
else
{
a[k].x=len;
a[k++].y=n2;
}
j=next[j];
}
}
}
int main()
{
int i,n,len,b,max;
while(scanf("%s",str)!=EOF)
{
k=0;
scanf("%d",&n);
for(i=1;i<=n;i++)
{
scanf("%s",s);
len=strlen(s);
NEXT(s,len);
kmp(s,str);
}
if(k==0)
printf("%d\n",strlen(str));
else
{
sort(a,a+k,cmp);
//for(i=0;i<k;i++)
//printf("x=%d y=%d\n",a[i].x,a[i].y);
max=a[0].x+a[0].y-1;
for(i=1;i<k;i++)
{
b=a[i].x+a[i].y-a[i-1].x-2;
if(b>max)
max=b;
}
b=len-1-a[k-1].x;
if(b>max)
max=b;
printf("%d\n",max);
}
}
return 0;
}