1. 程式人生 > >HDU 3068 最長迴文

HDU 3068 最長迴文

最長迴文

Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 31247    Accepted Submission(s): 11501  

Problem Description

給出一個只由小寫英文字元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

// manacher演算法
// 步驟 : 1. 處理字串,使其個數變為奇數
//        2. mancher( 3 種 判斷情況)
// 細節看程式碼
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
char s1[110009*2];
char s2[110009];
int P[110009*2];
int len;
void init( ){
	
	int i,j=2;
	s1[0]='$';
	s1[1]='#';
	for( i=0;i<len;i++){
		
		s1[j++] = s2[i];
		s1[j++] ='#';
		
	}
	s1[j] ='\0';
	len=j;
}
void manacher(){
	
	int i,id=0,mx=0;
	P[0]=0;
	for( i =1;i<=len;i++){
		
		if( mx > i)
		    P[i] = min( P[2*id-i],mx-i);
		else
		    P[i] = 1;
		
		while( s1[i+P[i] ] == s1[ i-P[i] ])
		         P[i]++;
		if( mx<P[i]+i){
			mx = P[i]+i;
			id = i;
		}         
		
	}
 	
}
int main(void){
   	while( scanf("%s",s2) !=EOF){
		int ans =-1;
		len = strlen(s2);
		init();
		manacher();
		for( int i=1;i<=len;i++){
			ans = max(ans,P[i]);
		}
		printf("%d\n",ans-1);
	}   	 
	
	return 0;
}