HDU 3068 最长回文(manacher算法:回文字串)
http://acm.hdu.edu.cn/showproblem.php?pid=3068
题意:给你一个串,求这个串中的最长回文字串的长度.
分析:
利用扩展KMP算法可以很轻松的求出原始串的后缀回文字串长.
详解请见HDU3613解题报告:
http://blog.csdn.net/u013480600/article/details/23041391
这里我们用S的逆T去匹配S,用扩展KMP算法,然后依次查看extend值取最大的extend值即可.extend[i]就是S的以S[i]为起点的回文字串的长度.
仔细一想,发现自己错了,扩展KMP只能判断前缀或后缀是不是回文,不能判断中间的字串是不是回文!
所以需要用manacher算法:
http://blog.csdn.net/u013480600/article/details/23060715
AC代码:
#include <iostream> #include<cstdio> #include<algorithm> #include<cstring> #include<cmath> using namespace std; const int MAXN=110000+1000; char S[MAXN*2];//构造的新串 char T[MAXN];//原始串 int n; int ans; int p[MAXN*2]; void init() { int i,j; S[0]='@',S[1]='#'; for(i=0,j=2;T[i];i++,j+=2) { S[j]=T[i]; S[j+1]='#'; } S[j]=0; } int manacher() { int ans=0; int id,i,mx=0; for(int i=1;S[i];i++) { if(mx>i) p[i]=min(p[2*id-i] , mx-i); else p[i]=1; while(S[i-p[i]] == S[i+p[i]]) p[i]++; if(i+p[i]>mx) { mx=i+p[i]; id=i; } ans = max(ans,p[i]-1); } return ans; } int main() { while(scanf("%s",T)==1) { init(); printf("%d\n",manacher()); } return 0; }