感觉这个题解挺不错的,自己理解了一下,还可以哦,哈,想不到还有这么一个O(n)的求最长回文串的算法。
http://blog.sina.com.cn/s/blog_6fa65cf90100s3sg.html
附上倆道的AC代码
hdu3068
#include<iostream> #include<algorithm> #include<string.h> #define maxn 111000 using namespace std; char str[maxn],str1[maxn*2]; int n,ans,nxt[maxn*2]; void Manacher() { memset(nxt,0,sizeof(nxt)); int mx=0,id; for(int i=1;i<n;i++) { if(mx>i) nxt[i]=min(nxt[2*id-i],mx-i); else nxt[i]=1; for(;str1[i-nxt[i]]==str1[i+nxt[i]];nxt[i]++); if(i+nxt[i]>mx) { mx=i+nxt[i]; id=i; } } } void pre() { int i=0,k=1,t=0; str1[0]='$'; while(str[i]!='\0') { str1[k++]=t?str[i++]:'#'; t^=1; } str1[k++]='#'; str1[k]='\0'; n=k; } int main() { while(scanf("%s",str)==1) { pre(); Manacher(); int maxx=0; for(int i=0;i<n;i++) if(maxx<nxt[i]-1) maxx=nxt[i]-1; printf("%d\n",maxx); } return 0; }
pku3974
#include<iostream> #include<algorithm> #include<string.h> #define maxn 1110000 using namespace std; char str[maxn],str1[maxn*2]; int n,ans,nxt[maxn*2]; void Manacher() { memset(nxt,0,sizeof(nxt)); int mx=0,id; for(int i=1;i<n;i++) { if(mx>i) nxt[i]=min(nxt[2*id-i],mx-i); else nxt[i]=1; for(;str1[i-nxt[i]]==str1[i+nxt[i]];nxt[i]++); if(i+nxt[i]>mx) { mx=i+nxt[i]; id=i; } } } void pre() { int i=0,k=1,t=0; str1[0]='$'; while(str[i]!='\0') { str1[k++]=t?str[i++]:'#'; t^=1; } str1[k++]='#'; str1[k]='\0'; n=k; } int main() { int cas=0; while(scanf("%s",str)==1) { if(strcmp(str,"END")==0) break; pre(); Manacher(); int maxx=0; for(int i=0;i<n;i++) if(maxx<nxt[i]-1) maxx=nxt[i]-1; printf("Case %d: %d\n",++cas,maxx); } return 0; }