poj 3974 马拉车算法及代码详解

点击打开链接
//manacher算法求最长回文子串,时间复杂度为O(n),基本思想是充分利用已求得的回文串长度
//关键是构造P数组
#include <iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
const int maxn=(1e6+5)*2;
int P[maxn];
int ans;
char T1[maxn];
char T2[maxn];
//P[i]-1恰好是位置i处的最长回文子串长度
//求解P数组
void Manacher(char T[])
{
        int pos=0,mx=0;             //mx为当前可以触及的最远位置,pos为这种状态时的对称轴位置
        P[0]=0;                 //0位置不考虑,为$标志
        for(int i=1;T[i];i++)
        {
            if(mx>i) P[i]=min(P[2*pos-i],mx-i);         //第一种情况:i在mx左侧,在左侧时又有两种情况:
            //两种情况:1.i关于pos的j的回文串较短 2.i关于pos的j的回文串较长,分别对应min中的两个值
            else P[i]=1;                    //i在mx右侧的情况
            while(T[i+P[i]]==T[i-P[i]]) P[i]++;                 //进行匹配
            if(mx<P[i]+i)                   //更新mx值和pos值
            {
                mx=P[i]+i;
                pos=i;
            }
            ans=max(ans,P[i]);
        }
}
// 构造T2串
//解决长度奇偶性带来的对称轴位置问题:在所有的空隙位置(包括首尾)插入一种原串中没有的符号,这样,奇数加偶数必为奇数
void init()
{
    int i,j=2;
    T2[0]='$',T2[1]='#';                //$符号是为了防止数组下标越界
    for(i=0;T1[i];i++)
    {
        T2[j++]=T1[i];
        T2[j++]='#';
    }
    T2[j]='\0';
}
int main()
{
    int kase=0;
    while(scanf("%s",T1)!=EOF)
    {
            if(T1[0]=='E') break;
            init();
            ans=0;
           Manacher(T2);
            printf("Case %d: %d\n",++kase,ans-1);
    }
    return 0;
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值