[字符串最长回文子串]hdoj 3068:最长回文

大致题意:
    给出一个只由小写英文字符a,b,c...y,z组成的字符串S,求S中最长回文串的长度。


大致思路:
    这题用后缀数组超时了……囧rz。其实这里用的是manacher算法,效率为O(n),比后缀数组的O(log n)要高。

算法详见http://blog.csdn.net/tanhaiyuan/article/details/7091019

#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
const int nMax=100005;
char str[nMax], str1[2*nMax];
int len,p[2*nMax];
void Build() {  //abc-->@#a#b#c#
    int i=0,j;
    str1[0]='@';//开始加入另特殊字符
    str1[1]='#';
    j=2;
    for(i=0; i<len; i++ ){//在每个字符两边都插入一个特殊字符
        str1[j++]=str[i];
        str1[j++]='#';
    }
    str1[j]='\0';
}

int manacher(){
    int idd,mxx=0,maxx=0,record;
    memset(p,0,sizeof(p));
    for(int i=1;str1[i]!='\0';i++){
        if( mxx>i )
            p[i]=min(mxx-i, p[2*idd-i]);
        else p[i]=1;
        while(str1[i+p[i]]==str1[i-p[i]])
            p[i]++;

        if( i+p[i]>mxx ){
            mxx=i+p[i];
            idd=i;
        }

        if( p[i]>maxx){
            maxx=p[i]-1;//P[id]-1就是该回文子串在原串中的长度
            record=i;
        }
    }
    return maxx;
}

int main(){
    int i, j,ans;
    while(scanf("%s",str)!=EOF){
        len=strlen(str);
        Build();
        ans=manacher();
        printf("%d\n",ans);
    }
}
 

你可能感兴趣的:(数据结构,字符串,ACM,hdoj 3068,最长回文)