杭电3336 Count the string

 1 /*
 2 写于13年3月16日
 3 http://acm.hdu.edu.cn/showproblem.php?pid=3336
 4 很巧妙的利用了KMP函数get_next()的思想
 5 通过对其进行改写达到目的
 6 data[i]表示[1....i-1]字符串出现的次数
 7 */
 8 
 9 #include <iostream>
10 #include <stdio.h>
11 #include <string.h>
12 using namespace std;
13 
14 char s[200005];
15 int next[200005];
16 int data[200005];
17 
18 void get_next(int n)
19 {
20     int j=0,i=1;
21     next[1]=0;
22     while(i<=n)
23     {
24         if(j==0||s[i]==s[j])
25         {
26             ++data[i];//字符串[1...i]第一次出现时置为1
27 
28             ++i;
29             ++j;
30             next[i]=j;
31             /*get_next的优化算法,但此处用不上
32             if(s[i]!=s[j])
33                 next[i]=j;
34             else
35                 next[i]=next[j];
36 
37             */
38             //j>1表示此时有s[i]==s[j],即有[1...j-1]出现第二次或更多次,j<n
39             if(j>1)
40                 ++data[j-1];
41         }
42         else
43             j=next[j];
44     }
45 }
46 int main()
47 {
48     int t;
49     int n;
50     scanf("%d",&t);
51     while(t--)
52     {
53         int ans=0;
54         scanf("%d",&n);
55         /*
56         for(int i=1;i<=n;i++)
57             scanf("%c",&s[i]);
58         此时%c接受空格回车等,就是在这里调试了一晚上,囧!
59 
60         */
61         scanf("%s",s+1);//字符串从s[1]开始
62         memset(data,0,sizeof(data));//讲data初始化
63         get_next(n);
64         for(int i=1;i<=n;i++)
65         {
66             //各个前缀出现的总次数和
67             ans=(ans+data[i])%10007;
68         }
69         ans=(ans)%10007;
70         printf("%d\n",ans);
71 
72     }
73     return 0;
74 }

 

posted on 2013-03-16 09:51  行者1992  阅读(193)  评论(0编辑  收藏  举报