题目1528:最长回文子串
来源:互联网 发布:照片排版软件 编辑:程序博客网 时间:2024/06/05 11:56
/*Mancher主算法。学习地址:http://blog.csdn.net/ggggiqnypgjg/article/details/6645824功能:求出以i为中心的回文半径p[i];参数:传入构造好的字符串长度特殊说明:因为前面加了一个无效字符,所以下标从1开始。*/#include <stdio.h>#include <string.h>#define N 200000+10char sb[N];char str[2*N];int dp[2*N];int n;int min(int x,int y){ if(x<y) return x; return y; }void pre(){ n=0; int i; for(i=1;sb[i];i++) { str[(i<<1)]=sb[i]; str[(i<<1)+1]='#'; } str[0]='?'; str[1]='#'; n=((i-1)<<1)+2; str[n]='\0'; // printf("%s\n",str); }int solve(){ int mx=0; int id=0; int maxlen=0; memset(dp,0,sizeof(dp)); // printf("@\n"); for(int i=1;i<n;i++) { if(mx>i) { dp[i]=min(dp[2*id-i],mx-i); } else { dp[i]=1; } for(;str[i-dp[i]]==str[i+dp[i]];dp[i]++); if(dp[i]+i>mx) { mx=dp[i]+i; id=i; } if(dp[i]>maxlen) { maxlen =dp[i]; } //printf("*\n"); } //printf("%d %d\n",id,mx); //for(int i=id;id<mx-1;i+=2) // printf("%c",str[i]); /* for(int i=1;i<n;i++) { printf("%c",str[i]); } printf("\n"); for(int i=1;i<n;i++) { printf("%d",dp[i]); } printf("\n"); */ return maxlen-1; }int main(){ while(scanf("%s",&sb[1])!=EOF) { pre(); int ans=solve(); printf("%d\n",ans); }return 0;}