最长回文 HDU - 3068

最长回文

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

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

猜你喜欢

转载自blog.csdn.net/yx970326/article/details/80034931