【HDU - 3068】最長迴文(Manacher演算法,馬拉車演算法求最長迴文子串)
阿新 • • 發佈:2018-11-01
題幹:
給出一個只由小寫英文字元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
解題報告:
裸的馬拉車演算法,一定注意修改後的陣列需要開二倍就好了,,,不然會RE但是我也不知道為什麼HDUoj報TLE很迷。。但是這題好像可以暴力啊。。跑出來都是200多ms。。
AC程式碼:
#include<cstdio> #include<iostream> #include<algorithm> #include<queue> #include<map> #include<vector> #include<set> #include<string> #include<cmath> #include<cstring> #define ll long long #define pb push_back #define pm make_pair #define fi first #define se second using namespace std; const int MAX = 2e5 + 5; int top; char s[110005],str[110005<<1]; int p[120005<<1]; int manacher() { if(top == 0) return 0 ; int maxx = -1; int c = -1,r = -1; for(int i = 1; i<top; i++) { p[i] = r>i ? min(p[2*c-i],r-i) : 1; // while(i+p[i]<top && i-p[i] > -1) { // if(str[i+p[i]] == str[i-p[i]]) p[i]++; // else break; // } for(;str[i-p[i]] == str[i+p[i]];p[i]++); if(i+p[i] > r) { r = i+p[i]; c=i; } maxx = max(maxx,p[i]); } return maxx-1; } int main() { while(~scanf("%s",s)) { int len = strlen(s); top=0; str[top++] = '@'; for(int i = 0; i<len; i++) { str[top++] = '#'; str[top++] = s[i]; } str[top++] = '#'; str[top] = '\0'; // printf("%s\n",str); printf("%d\n",manacher()); } return 0 ; }