hdu 3068 最长回文 (manacher)

最长回文
Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 29967    Accepted Submission(s): 10950

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

 

C/C++:

 1 #include <map>
 2 #include <queue>
 3 #include <cmath>
 4 #include <vector>
 5 #include <string>
 6 #include <cstdio>
 7 #include <cstring>
 8 #include <climits>
 9 #include <iostream>
10 #include <algorithm>
11 #define INF 0x3f3f3f3f
12 using namespace std;
13 const int my_max = 3e5;
14 
15 char my_str[my_max], my_temp[my_max];
16 int my_ans[my_max], len1, len2;
17 
18 void manacher()
19 {
20     int id = 0, mx = 0;
21     for (int i = 2; i < len2; ++ i)
22     {
23         if (mx > i) my_ans[i] = min(mx-i, my_ans[id*2 - i]);
24         else my_ans[i] = 1;
25         while (my_temp[i - my_ans[i]] == my_temp[i + my_ans[i]]) ++ my_ans[i];
26         if (my_ans[i] + i > mx)
27         {
28             mx = my_ans[i] + i;
29             id = i;
30         }
31     }
32 }
33 
34 int main()
35 {
36     while (~scanf("%s", my_str))
37     {
38         len1 = strlen(my_str);
39         my_temp[0] = '$';
40         my_temp[1] = '#';
41         for (int i = 0, j = 2; i < len1; ++ i, j += 2)
42         {
43             my_temp[j] = my_str[i];
44             my_temp[j + 1] = '#';
45         }
46         len2 = (len1 << 1) + 2;
47         my_temp[len2] = '*';
48 
49         manacher();
50         int temp = 0;
51         for (int i = 2; i < len2; ++ i)
52             if (temp < my_ans[i])
53                 temp = my_ans[i];
54 
55         printf("%d\n", temp - 1);
56     }
57 
58     return 0;
59 }

 

posted @ 2018-08-20 16:55  GetcharZp  阅读(103)  评论(0编辑  收藏  举报