Problem 2128 最长子串
Accept: 184 Submit: 693
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
分析:这题虽然比赛时没做出来,但是感觉还是不难的。
思路就是:对每个子串取出它在母串的位置,然后按位置排序。在考虑只出现一次情况下,对子串前后的字符长度考虑下,基本就可以做出来了。对细节不好考虑的话,就写一个案例出来,自己观察就好了!
让我无语的数组开小了,开小了,基本我没犯做这错好吧!最后吐槽,hdu上,会返回runtime error,这里只wa!
strstr(a,b)函数是返回,子串b在a中出现的第一次位置,是指针型的。没出现则返回 NULL.如果查找不区分大小写的话可以用 stristr();
#include<iostream>
#include<cstring>
#include<string>
#include<algorithm>
using namespace std;
struct a
{
int star,end;
}vis[1005];
bool cmp(a aa,a bb)
{
return aa.star<bb.star;
}
char s1[100006],s2[110];
int maxi(int a,int b)
{
return a>b?a:b;
}
int t,rel,ans,k;
int main()
{
while(scanf("%s",s1)!=EOF)
{
scanf("%d",&t);
rel=0,ans=-1;
for(int i=1;i<=t;i++)
{
scanf("%s",s2);
char *p;
char *c=s1;
while((p=strstr(c,s2))!=NULL)
{
k=p-s1;//子串在母串第一次位置
for(int i=0;i<strlen(s2);i++)//为第2次找子串准备
c=(++p);
vis[rel].end=k+strlen(s2)-1,vis[rel++].star =k;
}
}
if(!rel)//没有字串,长度就为母串
{
printf("%d\n",strlen(s1));
continue;
}
sort(vis,vis+rel,cmp);
int j;
j=vis[0].end;//子串前面的长度
ans=maxi(ans,j);
for(int i=1;i<rel;i++)
{
j=vis[i].end-vis[i-1].star-1;
ans=maxi(ans,j);
}
j=strlen(s1)-1-vis[rel-1].star; //子串后的长度
ans=maxi(ans,j);
printf("%d\n",ans);
}
return 0;
}