HDOJ3068最長迴文 ---- Manacher演算法
阿新 • • 發佈:2018-12-13
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
#include <iostream> #include <algorithm> #include <cstdio> #include <cstring> #define MAXN 110005 using namespace std; char old_s[MAXN];// 輸入的字串 char new_s[2*MAXN];// 轉換的新字串 int p[2*MAXN]; // 初始化 void Init() { memset(p,0,sizeof(p)); new_s[0] = '$';// 避免越界 new_s[1] = '#'; int len = strlen(old_s); int i = 0; int j = 2; while(i < len) { new_s[j++] = old_s[i++]; new_s[j++] = '#'; } new_s[j++] = '!';// 避免越界 new_s[j] = 0;// 字串分隔符 } // 馬拉車演算法 int Manacher() { int ret = 0;// 返回值 int mx = 2; int id = 1; p[1] = 1; int len = strlen(new_s); for (int i = 2; i < len - 1; i++) { if(i < mx) { p[i] = min(p[2*id-i],mx-i); } else { p[i] = 1; } while( new_s[i+p[i]] == new_s[i-p[i]]) p[i]++; if(i+p[i] > mx) { // 更新 mx = i + p[i]; id = i; } ret = max(ret,p[i]-1); } return ret; } int main() { while(scanf("%s",old_s) != EOF) { Init(); printf("%d\n",Manacher()); } return 0; }