hdu 3068 && pku 3974 (最长回文串)(Manacher 算法)

感觉这个题解挺不错的,自己理解了一下,还可以哦,哈,想不到还有这么一个O(n)的求最长回文串的算法。

http://blog.sina.com.cn/s/blog_6fa65cf90100s3sg.html

附上倆道的AC代码

hdu3068

#include<iostream>
#include<algorithm>
#include<string.h>
#define maxn 111000
using namespace std;
char str[maxn],str1[maxn*2];
int n,ans,nxt[maxn*2];
void Manacher()
{
    memset(nxt,0,sizeof(nxt));
    int mx=0,id;
    for(int i=1;i<n;i++)
    {
        if(mx>i)
            nxt[i]=min(nxt[2*id-i],mx-i);
        else nxt[i]=1;
        for(;str1[i-nxt[i]]==str1[i+nxt[i]];nxt[i]++);
        if(i+nxt[i]>mx)
        {
            mx=i+nxt[i];
            id=i;
        }
    }
}
void pre()
{
    int i=0,k=1,t=0;
    str1[0]='$';
    while(str[i]!='\0')
    {
        str1[k++]=t?str[i++]:'#';
        t^=1;
    }
    str1[k++]='#';
    str1[k]='\0';
    n=k;
}
int main()
{
    while(scanf("%s",str)==1)
    {
        pre();
        Manacher();
        int maxx=0;
        for(int i=0;i<n;i++)
            if(maxx<nxt[i]-1)
                maxx=nxt[i]-1;
        printf("%d\n",maxx);
    }
    return 0;
}
 
 
 
 
 
 
pku3974
#include<iostream>
#include<algorithm>
#include<string.h>
#define maxn 1110000
using namespace std;
char str[maxn],str1[maxn*2];
int n,ans,nxt[maxn*2];
void Manacher()
{
	memset(nxt,0,sizeof(nxt));
	int mx=0,id;
	for(int i=1;i<n;i++)
	{
		if(mx>i)
			nxt[i]=min(nxt[2*id-i],mx-i);
		else nxt[i]=1;
		for(;str1[i-nxt[i]]==str1[i+nxt[i]];nxt[i]++);
		if(i+nxt[i]>mx)
		{
			mx=i+nxt[i];
			id=i;
		}
	}
}
void pre()
{
	int i=0,k=1,t=0;
	str1[0]='$';
	while(str[i]!='\0')
	{
		str1[k++]=t?str[i++]:'#';
		t^=1;
	}
	str1[k++]='#';
	str1[k]='\0';
	n=k;
}
int main()
{
	int cas=0;
	while(scanf("%s",str)==1)
	{
		if(strcmp(str,"END")==0)
			break;
		pre();
		Manacher();
		int maxx=0;
		for(int i=0;i<n;i++)
			if(maxx<nxt[i]-1)
				maxx=nxt[i]-1;
		printf("Case %d: %d\n",++cas,maxx);
	}
	return 0;
}


 
原文地址:https://www.cnblogs.com/nanke/p/2212930.html