题目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;}

原创粉丝点击