一张图领悟Manacher算法,计算字符串最长回文子串
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3068
aaaa abab
4 3
代码:
#include<iostream> #include<cstring> using namespace std; string s; int p[110050*2]; // 这里需要注意,数组的长度大于字符串的长度的两倍; // 将字符串转换成奇字符串 void init() { memset(p,0,sizeof(p)); string s1="$"; for(int i=0;i<s.size();i++){ s1+='#'; s1+=s[i]; } s1+='#'; s=s1; } // 计算p[id]表示id位置的回文半径 void Manacher() { int id=0; // id位置的右边界最靠右(在已知范围内); int mx=0; // id的右边界位置; for(int i=1;i<s.size();i++){ if(mx>i) p[i]=min(p[2*id-i],mx-i); else p[i]=1; for(;s[i-p[i]]==s[i+p[i]];p[i]++); if(i+p[i]>mx){ mx=i+p[i]; id=i; } } } int main() { cin.sync_with_stdio(false); while(cin>>s){ init(); Manacher(); int ans=0; for(int i=1;i<s.size();i++){ if(ans<p[i]) ans=p[i]; } cout<<ans-1<<endl; } return 0; }