点击打开链接
//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;
}
poj 3974 马拉车算法及代码详解
最新推荐文章于 2020-07-24 16:34:36 发布