kmp典型例题讲解
hdu 3336 Count the string
http://acm.hdu.edu.cn/showproblem.php?pid=3336
其实这一题只要理解了kmp算法的核心
,就能迎刃而解了。利用kmp+dp;
Matrix67详解kmp:
http://www.matrix67.com/blog/archives/115/
kmp的核心就是要求出p数组(即next数组),而p【i】数组有一个特点:它的前j个数和最后j个数要相同。利用这个性质就可以得出递归表达式:dp[i]=dp[p[i]]+1;(+1是因为它本身肯定存在);
View Code
#include <iostream>
#include <memory.h>
#include <string.h>
#include <stdio.h>
using namespace std;
int p[10000100];
char ch[1000010];
void deal(int m){
int j=0;
p[1] = 0;
for(int i=2;i<=m;i++){
while(j>0 && ch[j]!=ch[i-1])j=p[j];
if(ch[j]==ch[i-1])j++;
p[i] = j;
//printf("%d\n",p[i]);
}
}
int main(){
int T,len,ans,t;
scanf("%d",&T);
while(T--){
scanf("%s",ch);
len = strlen(ch);
deal(len);
t = len - p[len];
if(t==len)
printf("%d\n",len);
else if(len%t==0)
printf("0\n");
else
printf("%d\n",t-len%t);
}
return 0;
}
总结:学习一个算法,一定要从原理上弄懂它。不然很难变通。
hdu 3746
Cyclic Nacklace
http://acm.hdu.edu.cn/showproblem.php?pid=3746
这一题其实不是很难,最主要的是最后面处理输出0时要注意下。
View Code
1 #include <iostream>
2 #include <stdio.h>
3 #include <memory.h>
4 using namespace std;
5 int p[200010];
6 char ch[2000010];
7 void deal(int m)
8 {
9 int j=0;
10 p[1] = 0;
11 for(int i=2;i<=m;i++)
12 {
13 while(j>0 && ch[j+1]!=ch[i])j=p[j];
14 if(ch[j+1]==ch[i])
15 {
16 j++;
17 }
18 p[i] = j;
19 //printf("%d\n",p[i]);
20 }
21
22 }
23 int main()
24 {
25 int T,n,dp[200010],ans;
26 scanf("%d",&T);
27 while(T--)
28 {
29 scanf("%d",&n);
30 getchar();
31 for(int i=1;i<=n;i++)
32 {
33 scanf("%c",&ch[i]);
34
35 }
36 memset(p,0,sizeof(p));
37 deal(n);
38 memset(dp,0,sizeof(dp));
39 //dp[n] = 1;
40 ans = 0;
41 for(int i=1;i<=n;i++)
42 {
43 dp[i]=(1+dp[p[i]])%10007;
44 ans=(ans+dp[i])%10007;
45 }
46 printf("%d\n",ans);
47 }
48 return 0;
49 }

浙公网安备 33010602011771号