首页 > 代码库 > hdu 3068 Manacher算法 O(n)回文子串算法
hdu 3068 Manacher算法 O(n)回文子串算法
题目:http://acm.hdu.edu.cn/showproblem.php?pid=3068
关于算法的教程 推荐这个:http://blog.csdn.net/ggggiqnypgjg/article/details/6645824 注意:我推荐的这篇博客里说的那个代码有bug,我觉得没问题,而是博主在用的时候写错了,博主举得反例我都过了 而且hdu 3068也过了
最开始是用的后缀数组,2000ms+ 果断超时...............
看过一遍很快就学会这个算法了:然后A掉
#include <string> #include <cstring> #include <cstdio> #include <algorithm> #include <iostream> #include <cstdlib> #include <vector> #define MAXN 200010 using namespace std; int p[MAXN],n; char str[MAXN],s[MAXN]; void pk() { int mx=0,id; for(int i=n; str[i]!=0; i++) str[i] = 0; for(int i=1;i<n;i++) { if(mx>i) p[i]=min(p[id*2-i],mx-i);//这里写成min(id*2-i,mx-i),WA得我快吐了 但是奇怪的是,还能跑328ms else p[i]=1; while(str[i-p[i]] == str[i+p[i]])p[i]++; if(i+p[i]>mx) { mx=p[i]+i; id=i; } } } void init() { int i,j; n=strlen(s); str[0]=‘$‘;//标记开头,可以用其他不会在测试样例中出现的字符,同样保证了在算p[i]的时候肯定不会越界,空字符肯定不等于$ str[1]=‘#‘;//间隔,可以用其他不会在测试样例中出现的字符 for(i=0,j=2;i<n;i++,j+=2) { str[j]=s[i]; str[j+1]=‘#‘; } str[j]=‘\0‘; n=j; } int getlen() { int ans=0; for(int i=0;i<n;i++) ans=max(ans,p[i]); return ans-1; } int main() { while(scanf("%s",s)!=EOF) { init(); pk(); printf("%d\n",getlen()); } return 0; }
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。