EOJ 3441-唐纳德与子串 (Easy)

来源:互联网 发布:c语言初学者看什么书 编辑:程序博客网 时间:2024/06/05 03:32

3441. 唐纳德与子串 (Easy)

Time limit per test: 1.0 seconds

Memory limit: 256 megabytes


题目链接:点击打开链接


子串的定义是在一个字符串中连续出现的一段字符。这里,我们使用 s[lr] 来表示 s 字符串从 l 到 r(闭区间)的子串。在本题中,字符串下标从 0 开始。显然,对于长度为 n 的字符串共有 n(n+1)2 个子串。

对于一个给定的字符串 s,唐纳德给出 q 次询问,第 i 次询问包括三个参数 li,ri,zi,问在 s[liri] 的所有子串中共有多少个恰好为 zi

Input

输入具有如下形式:

sql1 r1 z1l2 r2 z2lq rq zq

第一行一个字符串 s

第二行一个整数 q

接下来每行:首先两个整数 li,ri (0liri<|s|),然后是一个非空字符串 zi。整数和整数,整数和字符串间以单空格隔开。

字符串中只会出现 26 个小写英文字母。

数据规模约定:

  • 对于 Easy 档:1|s|100,q|zi|100
  • 对于 Hard 档:1|s|105,q|zi|105

Output

对于每次询问,输出一个整数,表示答案。


input
thisisagarbagecompetitionhahaha
5
0 30 a
1 5 is
25 30 hah
6 12 ag
7 12 ag


output
6
2
2
2
1


分析:

KMP的题,知识不是让你在文本串中匹配模式串,而是让你截取文本串中的某一部分对其进行匹配模式串的个数。练KMP的之后我就在c++的next数组里挣扎了好久,没想到这次又掉进去了,我滴天,套模板的题,早知道我就将next数组改个名字了。



#include<stdio.h>#include<string.h>#include<string>char s[1005],h[1005];int next[1005];int q,l,r,n;void get_next()///求得模式串的next数组{    next[0] = -1;    int k = -1;    for (int i = 1; i < n; i++)    {        while (k > -1 && h[k + 1] != h[i])        {            k = next[k];        }        if (h[k + 1] == h[i])        {            k = k + 1;        }        next[i] = k;    }}int KMP()///进行匹配{    get_next();    int k = -1;    int sum=0;    for (int i = l; i <= r; i++ )    {        while (k >-1&& h[k + 1] != s[i])        {            k = next[k];        }        if (h[k + 1] == s[i])            k = k + 1;        if (k == n-1)        {            sum++;        }    }    return sum;}int main(){    int ans;    scanf("%s",s);    scanf("%d",&q);    while(q--)    {        scanf("%d %d %s",&l,&r,h);        n=strlen(h);        ans=KMP();        printf("%d\n",ans);    }    return 0;}





原创粉丝点击