zoukankan      html  css  js  c++  java
  • hdu 3336 Count the String

    Count the string

    Time Limit : 2000/1000ms (Java/Other)   Memory Limit : 32768/32768K (Java/Other)
    Total Submission(s) : 5   Accepted Submission(s) : 3

    Font: Times New Roman | Verdana | Georgia

    Font Size:  

    Problem Description

    It is well known that AekdyCoin is good at string problems as well as number theory problems. When given a string s, we can write down all the non-empty prefixes of this string. For example:
    s: "abab"
    The prefixes are: "a", "ab", "aba", "abab"
    For each prefix, we can count the times it matches in s. So we can see that prefix "a" matches twice, "ab" matches twice too, "aba" matches once, and "abab" matches once. Now you are asked to calculate the sum of the match times for all the prefixes. For "abab", it is 2 + 2 + 1 + 1 = 6.
    The answer may be very large, so output the answer mod 10007.

    Input

    The first line is a single integer T, indicating the number of test cases.
    For each case, the first line is an integer n (1 <= n <= 200000), which is the length of string s. A line follows giving the string s. The characters in the strings are all lower-case letters.

    Output

    For each case, output only one number: the sum of the match times for all the prefixes of s mod 10007.

    Sample Input

    1
    4
    abab

    Sample Output

    6



    看了喵呜的解题报告才知道这么做的:

    这题是KMP的变形题,主要是了解next数组的用法。

    题意是,给一串字符串,问这串字符串所有的前缀总共在这个字符串中出现了几次。

    已经有了next数组,next[i]=j表示最大的j使得0~j==i-j~i,因此,对于样例abab,则有

           0   1   2   3

    b[]  a    b   a   b

    p[]  -1  -1  0   1

    对于4个前缀:

    a

    ab

    aba

    abab

    设dp[i]表示子串b[0~i]共含有以b[i]为结尾的前缀的数目,则以b[i]结尾的前缀数就是自己本身加上以b[p[i]]结尾的前缀数,也就是例如i=2

    则有:

    a

    aba这两个前缀,其中a就是b[p[i]]结尾的前缀。


    View Code
     1 #include <iostream>
     2 #include <stdio.h>
     3 using namespace std;
     4 
     5 int dp[200005];
     6 char b[200005];
     7 int p[200005];
     8 int n;
     9 
    10 int find()
    11 {
    12     int ans=1;
    13     int i,j;
    14     dp[0]=1;
    15     j=-1;
    16     p[0]=-1;
    17     for(i=1;i<n;i++)
    18     {
    19         while(j>=0 && b[j+1]!=b[i]) j=p[j];
    20         if(b[j+1]==b[i]) j++;
    21         if(j>=0) dp[i]=(dp[j]+1)%10007;        // 出去这两行就是原来简单的KMP 就pre数组。
    22         else  dp[i]=1;                            //
    23         p[i]=j;
    24         ans=(ans+dp[i])%10007;
    25     }
    26     return ans;
    27 }
    28 
    29 int main()
    30 {
    31     int i,j,t;
    32     scanf("%d",&t);
    33     while(t--)
    34     {
    35         scanf("%d",&n);
    36         scanf("%s",b);
    37         printf("%d\n",find());
    38     }
    39     //system("pause");
    40     return 0;
    41 }

    对于这一题还有个比较耗时间的做法:

    1、首先确定下这个字符串的首个字母,然后从第二个开始搜起
    当遇到和首字符一样的时候,就从该字母开始和这个字符串的首
    字符开始进行比较,知道出现不一样为止,此时相同的个数就
    加到总数上。
    2、不一样的话就从和首个字符一样的位置的下一个字符开始。
    然后和1步骤差不多,就是这个字符和首个字符往后走,遇到不
    一样又重复这个步骤。。。
     
    代码如下:
    View Code
     1 #include <iostream>
     2 #include <stdio.h>
     3 #include <string.h>
     4 using namespace std;
     5 
     6 char str[200005];
     7 
     8 int main()
     9 {
    10     int i,j,n,sum;
    11     int t;
    12     scanf("%d",&t);
    13     while(t--)
    14     {
    15         scanf("%d",&n);
    16         sum=n;
    17         sum=sum%10007;
    18         scanf("%s",str);
    19         for(i=1;i<n;i++)
    20         {
    21             if(str[i]==str[0])
    22             {
    23                 for(j=i;j<n;j++)
    24                 {
    25                     if(str[j]!=str[j-i])
    26                         break;
    27                 }
    28 
    29                 sum+=j-i;
    30                 sum=sum%10007;
    31             }
    32         }
    33         printf("%d\n",sum);
    34     }
    35     return 0;
    36 }
  • 相关阅读:
    机器学习入门-文本数据-使用聚类增加文本的标签属性
    机器学习入门-文本特征-使用LDA主题模型构造标签 1.LatentDirichletAllocation(LDA用于构建主题模型) 2.LDA.components(输出各个词向量的权重值)
    机器学习入门-文本特征-word2vec词向量模型 1.word2vec(进行word2vec映射编码)2.model.wv['sky']输出这个词的向量映射 3.model.wv.index2vec(输出经过映射的词名称)
    机器学习入门-数值特征-对数据进行log变化
    python中datetime.strptime(),strftime()的应用
    css中的','、'>'、'+'、'~'
    js中const,var,let区别
    css的#和.的区别
    js实现拖放
    [Usaco2005]Part Acquisition
  • 原文地址:https://www.cnblogs.com/shenshuyang/p/2607665.html
Copyright © 2011-2022 走看看