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

浙公网安备 33010602011771号