最长回文
HDU - 3068
给出一个只由小写英文字符a,b,c...y,z组成的字符串S,求S中最长回文串的长度.
回文就是正反读都是一样的字符串,如aba, abba等
Input 输入有多组case,不超过120组,每组输入为一行小写英文字符a,b,c...y,z组成的字符串S
两组case之间由空行隔开(该空行不用处理)
字符串长度len <= 110000 Output 每一行一个整数x,对应一组case,表示该组case的字符串中所包含的最长回文长度.
Sample Input
给出一个只由小写英文字符a,b,c...y,z组成的字符串S,求S中最长回文串的长度.
回文就是正反读都是一样的字符串,如aba, abba等
Input 输入有多组case,不超过120组,每组输入为一行小写英文字符a,b,c...y,z组成的字符串S
两组case之间由空行隔开(该空行不用处理)
字符串长度len <= 110000 Output 每一行一个整数x,对应一组case,表示该组case的字符串中所包含的最长回文长度.
Sample Input
aaaa
abab
Sample Output
4
3
code:
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
const int maxn=110005;
char str[maxn];
char news[maxn*2];
int p[maxn*2];
int newlen;
int Getnew(){
int index=2;
int len=strlen(str);
news[0]='@';
news[1]='#';
for(int i=0;i<len;i++){
news[index++]=str[i];
news[index++]='#';
}
news[index]='\0';
return index;//返回重新构建的字符串长度
}
int Manacher(int newlen){
int mx=0,id=0;
int ans=0;
for(int i=1;i<newlen;i++){
if(i<mx){
p[i]=min(p[id*2-i],mx-i);
}
else{
p[i]=1;
}
while(news[i-p[i]]==news[i+p[i]])p[i]++;
if(p[i]+i>mx){
mx=p[i]+i;//更新mx(最远可达的地方)
id=i;
}
ans=max(ans,p[i]-1);//注意此处p[i]-1刚好是原字符串中回文串的长度
//上面一行可替换为下面一行,注意若替换则需要返回ans-1
//ans=max(ans,p[i]);
}
return ans;//差点忘了返回最长回文串的长度
}
int main(){
while(scanf("%s",str)!=EOF){
newlen=Getnew();
int maxlen=Manacher(newlen);
cout<<maxlen<<endl;
}
return 0;
}