fzu---2128

题目链接:http://acm.hust.edu.cn/vjudge/contest/128687#problem/G

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
 
analyse:

依次找出每个子串的在字符串中的首尾地址,所有子串先按照尾地址从小到大排序。然后首地址从小到大排。

遍历一遍每个子串的首地址和它后面相邻子串的尾地址之差-1.

st1----------ed1

-------st2------------ed2

例如这种情况说明,可能出现的一个maxx就是 ed2和st1之间的字符个数。这时候没有ed2最后一个字符,st1第一个字符,所以不包含str1和str2.

关于找每个子串的位置,有两种方法,kmp和strstr.

注意数组的长度

#include <cstdio>
#include <cstring>
#include <iostream>
#include <cmath>
#include<vector>
#include<queue>
#include<algorithm>

using namespace std;
typedef long long LL;

const int maxn=1000009;
const int INF=0x3f3f3f3f;
const int mod=2009;

char str[maxn];
char str1[1100][110];
struct node
{
    int s, e;
} a[maxn];

int cmp(node A, node B)
{
    if(A.e != B.e)
        return A.e<B.e;
    return A.s < B.s;
}

int main()
{
    while(~scanf("%s", str))
    {
        int n, k=0, cnt;
        scanf("%d", &n);
        for(int i=0; i<n; i++)
            scanf("%s", str1[i]);

        for(int i=0; i<n; i++)
        {
            int len=strlen(str1[i]);
            cnt=0;
            while(strstr(str+cnt, str1[i])!=NULL)
            {
                int s=strstr(str+cnt, str1[i])-str;
                a[k].s=s;
                a[k++].e=s+len-1;
                cnt=s+len-1;
            }
        }

        a[k].s=0;
        a[k++].e=strlen(str);
        sort(a, a+k, cmp);

        int maxx=-INF;
        for(int i=k-1; i>0; i--)
        {
            int x=a[i].e-a[i-1].s-1;
            maxx=max(maxx, x);
        }

        if(maxx==-INF)
            maxx=strlen(str);
        printf("%d\n", maxx);
    }
}

 

posted @ 2016-08-22 21:49  爱记录一切美好的微笑  阅读(193)  评论(0编辑  收藏  举报