ACM练习之《自然的谜语》
2014-05-15 23:47
141 查看
然后说说我刷题之路遇到的第二题吧:《PID328/自然地谜语》。
5月13号中午,复习了string类后,用str.compare()函数很快搞定了这道题,哈哈,不过提交后只得了80分,显示TLE,百度:超出时间限制。看了一下最后两个测评超时了。。完全没接触过超时啊,这可怎么改。看了一下评论,貌似必须用一个KMP算法。。。艹,学!看不懂有木有。。。于是Google了好几个版本的教程,下到手机上,不断地看不断地研究……(顺便认识了一个BF算法,复习了指针一堆东西,引用等等。。好吧,我承认我TM快把去年学的东西忘光了。。。)
KMP学习文章一:http://www.ruanyifeng.com/blog/2013/05/Knuth%E2%80%93Morris%E2%80%93Pratt_algorithm.html
KMP学习文章二:/article/4719933.html
KMP学习文章三:/article/5631720.html
附上BF与KMP练习代码:
5月14号,带着稍稍能看懂那么一点的KMP算法,重写了这一题,提交检测成果……靠,服务器坏了 - -。
2014年5月16日23:46:25更新:
NND,服务器终于好了,TM一看竟然WA30,大失所望。排查出错误后再提交,最后三个测试点超时 - -。再改。又错。再改。又超时……
无奈了,问队友曹大神,果然他也WA了几次,哈哈。不过还是被他分分钟AC了 - -。看他的代码,感觉和我的差不多啊。。。郁闷。改来改去无效。放下不管了。。。
晚上,决定删了自己的代码仿着曹大神的重写,可是,竟然又有两道超时
。。。我可抄的就剩输入输出不一样了。。。换成他的输出函数,果然AC了。。。然后曹大神告诉我,cin和cout超级慢……(有时可在主函数使用 ios::sync_with_stdio(false);能加快速度)。
额额额,好吧,又涨姿势了:scanf + printf 要比 cin + cout 运行快。
唉,不管怎么说,今天终于算是把这道题解决了。看得出来我欠的知识实在太多,需要努力啊。
附上曹大神解此题的源代码:(很多地方值得我去学习
)
5月13号中午,复习了string类后,用str.compare()函数很快搞定了这道题,哈哈,不过提交后只得了80分,显示TLE,百度:超出时间限制。看了一下最后两个测评超时了。。完全没接触过超时啊,这可怎么改。看了一下评论,貌似必须用一个KMP算法。。。艹,学!看不懂有木有。。。于是Google了好几个版本的教程,下到手机上,不断地看不断地研究……(顺便认识了一个BF算法,复习了指针一堆东西,引用等等。。好吧,我承认我TM快把去年学的东西忘光了。。。)
KMP学习文章一:http://www.ruanyifeng.com/blog/2013/05/Knuth%E2%80%93Morris%E2%80%93Pratt_algorithm.html
KMP学习文章二:/article/4719933.html
KMP学习文章三:/article/5631720.html
附上BF与KMP练习代码:
#include <iostream> #include <cstring> using namespace std; int KMPMatch(char *s,char *p); int BFMatch(char *s, char *p); void getNext(char *p,int *next); int main() { char s1[11] = {'a','b','a','b','c','a','b','a','b','a'}; char s2[6] = {'a','b','a','b','c'}; cout << BFMatch(s1 , s2) << endl; cout << KMPMatch(s1 , s2) << endl; return 0; } //BF算法 int BFMatch(char *s , char *p) { int i,j; i=0; while(i<strlen(s)) { j=0; while(s[i]==p[j]&&j<strlen(p)) { i++; j++; } if(j==strlen(p)) return i-strlen(p); i = i - j + 1 ; //指针i回溯 } return -1; } //KMP算法 int KMPMatch(char *s,char *p) { int next[100]; int i,j; i=0; j=0; getNext(p,next); while(i<strlen(s)) { if(j==-1||s[i]==p[j]) { i++; j++; } else { j=next[j]; //消除了指针i的回溯 } if(j==strlen(p)) return i-j; } return -1; } void getNext(char *p,int *next) { int j,k; next[0]=-1; j=0; k=-1; while(j<strlen(p)-1) { if(k==-1||p[j]==p[k]) //匹配的情况下,p[j]==p[k] { j++; k++; next[j]=k; } else //p[j]!=p[k] k=next[k]; } }
5月14号,带着稍稍能看懂那么一点的KMP算法,重写了这一题,提交检测成果……靠,服务器坏了 - -。
2014年5月16日23:46:25更新:
NND,服务器终于好了,TM一看竟然WA30,大失所望。排查出错误后再提交,最后三个测试点超时 - -。再改。又错。再改。又超时……
无奈了,问队友曹大神,果然他也WA了几次,哈哈。不过还是被他分分钟AC了 - -。看他的代码,感觉和我的差不多啊。。。郁闷。改来改去无效。放下不管了。。。
晚上,决定删了自己的代码仿着曹大神的重写,可是,竟然又有两道超时
。。。我可抄的就剩输入输出不一样了。。。换成他的输出函数,果然AC了。。。然后曹大神告诉我,cin和cout超级慢……(有时可在主函数使用 ios::sync_with_stdio(false);能加快速度)。
额额额,好吧,又涨姿势了:scanf + printf 要比 cin + cout 运行快。
唉,不管怎么说,今天终于算是把这道题解决了。看得出来我欠的知识实在太多,需要努力啊。
附上曹大神解此题的源代码:(很多地方值得我去学习
)
#include<iostream> #include<cstring> #include<cstdio> using namespace std; const int MAXN = 100010,MAXM = 100010; char T[MAXN],P[MAXM]; int Next[MAXM],N,M,C; int Ans[MAXN]; void MakeNext(int M) { int i=0,j=-1; Next[i] = -1; while(i<M) { if(j==-1||P[i]==P[j])Next[++i] = ++j; else j = Next[j]; } } int KMP(int pos,int N,int M) { int i = pos, j = 0,ans = 0; while(i<N){ if(T[i]==P[j]||j==-1)i++,j++; else j = Next[j]; if(j==M){ Ans[++ans]=i-j+1; j = Next[j-1]; i--; } } return ans; } int main() { scanf("%s%s",P,T); N = strlen(T),M = strlen(P); MakeNext(M); int ans=KMP(0,N,M); if(ans==0) { puts("There must be something wrong."); return 0; } printf("%d\n",ans); for(int i=1;i<=ans;i++) printf("%d\n",Ans[i]); return 0; }
相关文章推荐
- ACM递推递归练习总结
- acm课程练习2--1003
- ACM练习—公约数和公倍数
- ACM第三次练习—1014
- acm练习-day1
- sdutacm-图结构练习——BFSDFS——判断可达性
- 第十七周自由练习项目——acm 抽象基类
- 第十七周自由练习项目——acm 学生最高最低成绩
- 第十九周自由练习项目——acm 输出日期时间类——友元类
- ACM天梯赛练习L1-005. 考试座位号
- ACM 算法 阶段性练习
- ACM天梯赛练习L1-021. 重要的话说三遍
- ACM程序设计书中的题目练习后感
- Acm练习(六)
- ACM-递归递推练习H-三国佚事——巴蜀之危
- ACM第一次练习-1004
- ACM练习建议
- acm练习:素数求和问题
- ACM 3117 高精度练习之乘法(基础)
- ACM第二次练习—1001