# KMP经典入门题

hdu 1358 找循环节、求字符串周期，简单题，题面简洁。

#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<iostream>
using namespace std;
const int sz=1e6+5;
char s[sz];
int fail[sz];
int main()
{
int cas=0;
for(;;)
{	int n,len,i,p;
scanf("%d",&n); if(n==0) break;
scanf("%s",s+1); len=strlen(s+1);
printf("Test case #%d\n",++cas);
fail[0]=-1; fail[1]=0;
for(i=2;i<=len;i++)
{	p=fail[i-1];
while(p>=0&&s[p+1]!=s[i]) p=fail[p];
if(p<0) fail[i]=0;
else fail[i]=p+1;
if(fail[i]&&i%(i-fail[i])==0) printf("%d %d\n",i,i/(i-fail[i]));
}
printf("\n");
}
return 0;
}


hdu 1686 匹配，求出现次数；与POJ3461是完全相同的题目。

#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<iostream>
using namespace std;
const int sz=1e6+4;
char s1[sz],s2[sz];
int fail[sz];
int main()
{
int cas; cin>>cas;
while(cas--)
{	int len1,len2,i,p;
scanf("%s%s",s1+1,s2+1);
len1=strlen(s1+1); len2=strlen(s2+1);
memset(fail,0,sizeof(fail)); fail[0]=-1;
for(i=1;i<=len1;i++)
{	for(p=fail[i-1];p>=0&&s1[p+1]!=s1[i];p=fail[p]);
if(p<0) fail[i]=0;
else fail[i]=p+1;
}
int ans=0;
for(i=1,p=0;i<=len2;i++)
{	for(;p>=0&&s1[p+1]!=s2[i];p=fail[p]);
if(++p==len1){ans++; p=fail[p];}
}
printf("%d\n",ans);
}
return 0;
}