1. 程式人生 > 實用技巧 >A - 最長迴文(馬拉車演算法//manacher)

A - 最長迴文(馬拉車演算法//manacher)

給出一個只由小寫英文字元a,b,c...y,z組成的字串S,求S中最長迴文串的長度. 迴文就是正反讀都是一樣的字串,如aba, abba等

Input輸入有多組case,不超過120組,每組輸入為一行小寫英文字元a,b,c...y,z組成的字串S
兩組case之間由空行隔開(該空行不用處理)
字串長度len <= 110000Output每一行一個整數x,對應一組case,表示該組case的字串中所包含的最長迴文長度.
Sample Input

aaaa

abab

Sample Output

4
3
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <algorithm>
using
namespace std; char s[110005]; char ma[110005]; int mp[110005]; void manacher(char s[],int len) { int l=0; ma[l++]='$'; ma[l++]='#'; for(int i=0;i<len;i++) { ma[l++]=s[i]; ma[l++]='#'; } /* a b a b c */ /*$ # a # b # a # b # c # */ ma[l]='\0'; int
mx,id;//mx為以id為中心的最長迴文串的右界 id+p[id]=mx [id-p[id]~mx] //若遍歷到i,有i<mx :if(i<mx) p[i]=min(p[j=2*id-i],mx-i) for(int i=0;i<l;i++) { mp[i]=mx>=i?min(mp[2*id-i],mx-i):1; while(ma[i+mp[i]]==ma[i-mp[i]]) // 不需邊界判斷,因為左有'$',右有'\0' mp[i]++;//j 迴文串左端正好與 id 的迴文串左端重合時
// 我們每走一步 i,都要和 mx 比較,我們希望 mx 儘可能的遠,這樣才能更有機會執行 if (i < mx)這句程式碼,從而提高效率 if(i+mp[i]>mx)//更新 id,mx; { mx=i+mp[i]; id=i; } } } int main() { while(~scanf("%s",s)) { int len=strlen(s); int ans=0; manacher(s,len); for(int i=0;i<2*len+2;i++) ans=max(ans,mp[i]-1);//性質:最長迴文長度=mp[i]-1; mp[i]個'#',mp[i]-1個字元,原長2*mp[i]-1; printf("%d\n",ans); } }