hdu-3068-最长回文(manacher算法模板)
1 /* 2 Name:hdu-3068-最长回文 3 Copyright: 4 Author: 5 Date: 2018/4/24 16:12:45 6 Description: 7 manacher算法模板 8 */ 9 #include <iostream> 10 #include <cstdio> 11 #include <string> 12 #include <cstring> 13 #include <math.h> 14 #include <algorithm> 15 using namespace std; 16 const int MAXN = 110005 * 2;//字符串长度*2 17 18 void manacher(char str[],int len[],int n){//接口 19 len[0] = 1; 20 for(int i = 1,j = 0; i < (n<<1) - 1;++ i){ 21 int p = i >> 1,q = i - p, r = ((j+1) >> 1) + len[j] - 1; 22 len[i] = r < q?0:min(r-q+1,len[(j<<1) - i]); 23 while(p > len[i] - 1 && q + len[i] < n && str[p - len[i]] == str[q+len[i]]) ++len[i]; 24 if(q + len[i] - 1 > r) j = i; 25 } 26 } 27 struct Solution { 28 string longestPalindrome(string s) { 29 int n = s.size(); 30 int len[MAXN]; 31 char *str = &s[0]; 32 manacher(str,len,n);//调用接口,得到len[] 33 string tmp = ""; 34 int pos = 0,max_len = 0; 35 for(int i = 0;i < (n<<1) - 1; ++ i){ 36 int tmp_len = (i&1)?len[i]<<1:(len[i]<<1)-1; //以‘#’or字符为中心,串长不一样 37 if(tmp_len > max_len) pos = i,max_len = tmp_len; //pos记录目标串的中心点,max_len表示目标串的串长(不含#) 38 if(i&1) tmp+="#"; else tmp+=s[i>>1]; //作一个tmp[0..2n-1]的字符串,便于输出 39 } 40 if(pos&1){ //找到要打印的串tmp的起始位置pos和打印长度max_len(便于打印输出) 41 max_len = (len[pos] << 2) - 1; 42 pos = pos - (len[pos] << 1) + 1; 43 } 44 else{ 45 max_len = (len[pos] << 2) - 3; 46 pos = pos - ((len[pos]-1)<<1); 47 } 48 string ans = ""; 49 for(int i = pos,j = 0;j < max_len;++ j,++ i){ 50 if(i&1) continue; 51 ans+=tmp[i]; //tmp中找到所要打印的字符,链接起来 52 } 53 return ans; 54 } 55 }; 56 57 int main() 58 { 59 // freopen("in.txt", "r", stdin); 60 string str; 61 while (cin >> str) { 62 getchar(); 63 Solution tmp; 64 cout<<tmp.longestPalindrome(str).size()<<endl; 65 } 66 return 0; 67 }