hdu 3336 Count the string
之前发现把题目的网页复制过来显的文章不太好,以后就不这么做了。杭州回来跟死了一样,发誓我要踏踏实实一步一步来。
这个题是kmp的题,题目意思大概是对于原串中的每个前缀,找这个前缀在原串中出现过几次,对每个前缀都这么做,并用一个计数器来累加,最后要输出的就是这个结果%10007。这个题我tle了一次,主要是现在已经懒得算什么时间复杂度了,之前赛场上我队友非要n^2搞一个一百亿的数据量,我无语到吐血。。。
tle代码:主要思想就是搞出来每个前缀并与原串进行KMP,时间复杂度不是很清楚,反正是挂掉了。后来自己胡乱想了一个想法,就是next数组搞出来的是前后缀问题,那么我就可以考察next数组,看对于其中的每一位会用它进行几次匹配。自己瞎想的,说不清楚,看之后的ac代码哇。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include <algorithm> #include <iostream> #include <cstdlib> #include <cstring> #include <cstdio> using namespace std; const int maxn=200000+5; char s[maxn]; string str; int n,ans,len,next[maxn]; void init() { ans=0; memset(s,0,(n+5)*sizeof(char)); } void data_in() { getchar(); scanf("%s",s); // cout<<s<<endl; } void get_next() { int i=0,j=-1; next[0]=-1; while(i<len) { if(j==-1||s[i]==s[j]) i++,j++,next[i]=j; else j=next[j]; } } void KMP() { int j=-1; for(int i=0;i<len;i++) { while(j>-1&&str[j+1]!=s[i]) j=next[j]; if(str[j+1]==s[i]) j++; if(j==str.length()-1) { ans++; j=next[j]; } } } void cal() { len=strlen(s); get_next(); // for(int i=0;i<=len;i++) // cout<<next[i]<<endl; // cout<<endl; for(int i=0;i<len;i++) { str=""; for(int j=0;j<=i;j++) str+=s[j]; // cout<<str<<endl; KMP(); } printf("%d\n",ans); } int main() { int ncas; scanf("%d",&ncas); while(ncas--) { scanf("%d",&n); init(); data_in(); cal(); } return 0; }
ac代码:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include <algorithm> #include <iostream> #include <cstdlib> #include <cstring> #include <cstdio> using namespace std; const int maxn=200000+5; char s[maxn]; string str; int n,ans,len,next[maxn]; void init() { ans=0; memset(s,0,(n+5)*sizeof(char)); } void data_in() { getchar(); scanf("%s",s); // cout<<s<<endl; } void get_next() { int i=0,j=-1; next[0]=-1; while(i<len) { if(j==-1||s[i]==s[j]) i++,j++,next[i]=j; else j=next[j]; } } void cal() { len=strlen(s); get_next(); // for(int i=0;i<=len;i++) // cout<<next[i]<<endl; // cout<<endl; for(int i=len;i>=0;i--) { int j=i; while(next[j]!=-1) { ans++; j=next[j]; } } printf("%d\n",ans%10007); } int main() { int ncas; scanf("%d",&ncas); while(ncas--) { scanf("%d",&n); init(); data_in(); cal(); } return 0; }
以后会每天都来博客转转,在我的那本书:柔性字符串匹配,回来之前或者回来以后,我都会接着把kmp,字典树,ac自动机,后缀自动机的题目一一找来做,自己先思考,是在做不出再去百度题解。我相信自己,虽然我已经想好了要放弃了,但还在坚持,因为我该做的还没有做完,内心深处给自己布置的那几本书还没有看完。总之就一切跟着刷题转。我qq405948382,有兴趣的朋友一起哇,我是菜鸟,求组队,但是不求虐,伤不起了!
勸君惜取少年時&莫待無花空折枝
posted on 2012-11-08 16:22 Raining Days 阅读(164) 评论(0) 编辑 收藏 举报