HDU 3336 Count the string

来源:互联网 发布:淘宝手机店铺首页尺寸 编辑:程序博客网 时间:2024/04/28 07:48

这里写图片描述

题目大意:求字符串中【前缀+跟前缀相同的子串】的个数!

解题思路:这道题是一道简单的KMP模板的变型题,主要考察的是对于next数组的理解!数组next[i]表示前i个字符所组成的字符串的最大前后缀匹配长度

对于第一组测试数据

下标 0 1 2 3 4 测试用例 a b a b next值 -1 0 0 1 2

测试数据答案打印出来的是6 那么我们把出现的情况一 一列举出来:

出现情况 总数 a 2次 ab 2次 aba 1次 abab 1次

所以最终答案是2+2+1+1=6

下面就是我们怎么来求出这个答案了?

我们可以从next数组来求出这个对应的个数

首先我们开个for循环从1开始遍历直到这个给出字符串的长度截止,就拿测试用例给出的abab来举例

设一个总数量cnt=0。

当i=1时,j=i=1,此时j不等于0。让cnt++,之后把next[j]=0赋值给j,此时j为零 跳出里层循环 正好对应abab出现1次

当i=2时,j=i=2,cnt++,把next[j]=next[2]=0赋值给j,此时j为零 跳出里层循环 正好对应aba出现1次

当i=3时,j=i=3,cnt++,把next[j]=next[3]=1赋值给j,因为此时j不为零,开始如j=1一样循环,这样cnt会加2次才会跳出里层循环 正好对应ab出现2次

当i=4时,j=i=4,cnt++,把next[j]=next[4]=2赋值给j,因为此时j不为零,开始如j=2一样循环,这样cnt会加2次才会跳出里层循环 正好对应a出现2次

这样cnt最会跳出外层for循环就是字符串中前缀+跟前缀相同的子串的个数

程序说明了要对10007取余 注意在里层循环中加上if判断 最终结果也要对10007取余

下面就上代码了

#include <iostream>#include <cstdio>#include <cstring>#include <cstdlib>#include <algorithm>#include <map>#include <cmath>#include <queue>#include <string> #define mod(get_next,b)  get_next%b;#define printf(cnt) printf("%d\n",cnt);const int maxn=200005;char str[maxn];int get_next[maxn];int n;void init(int len){     int i=-1,j=0;     get_next[0]=-1;     while(j<len)     {         if(i==-1||str[i]==str[j])         {             ++i,++j;             get_next[j]=i;         }         else          i=get_next[i];     }     /*for(int i=0;i<=len;i++)         cout<<get_next[i]<<" ";         cout<<endl;*/}int main(){    int t;    scanf("%d",&t);    while(t--)    {        int cnt=0;        scanf("%d %s",&n,str);        init(n);//初始化next数组        cnt=0;        for(int i=1;i<=n;i++)//精髓所在        {            int j=i;            while(j!=0)            {                cnt++;                if(cnt>10007)                    cnt=mod(cnt,10007);                j=get_next[j];            }        }        printf(cnt);    }    return 0;}
4 0
原创粉丝点击