试着写写题解,不知道以后会不会养成习惯。。。
前一阵子复习KMP,又回去找了几道入门题写写。。。
切水找找1A的感觉orz。以下大致都是一句话+代码的形式。实在是懒。
不过我是复习,本来也没什么好说的。
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;
}
诶,还是顺便说下吧,我的KMP是自己学的,不,应该说是自己理解之后按照自己的思路写的。
然后写成了现在这个样子的完全就和很多资料不同了。。
当然主要差别无非就是,我的数组下标从1开始而一般的从0开始,然后我写的是“fail[]”数组而不是“next[]”数组。。。
我自己喜欢就好啦~
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;
}
这大概就是两道经典入门题吧。。
第一次写博客,第一次发代码,先这样。。。我看看效果。。