题目链接
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 }