求一个字符串的最长子串,Manacher算法是一种O(n)的算法,很给力!

s2[0] = '$',是避免在循环中对数组越界的检查。

 

模板题,没有什么好说的。Manacher算法本身确实是要好好理解体会的。

 

HDU 3068 (Manacher) 最长回文_manacher算法HDU 3068 (Manacher) 最长回文_#include_02
 1 #define LOCAL
 2 #include <iostream>
 3 #include <cstdio>
 4 #include <cstring>
 5 #include <algorithm>
 6 using namespace std;
 7 
 8 const int maxn = 110000 + 20;
 9 char s1[maxn], s2[maxn * 2];
10 int p[maxn * 2];
11 
12 void init(char s1[], char s2[])
13 {
14     s2[0] = '$', s2[1] = '#';
15     int j = 2;
16     for(int i = 0; s1[i] != '\0'; ++i)
17     {
18         s2[j++] = s1[i];
19         s2[j++] = '#';
20     }
21     s2[j] = '\0';
22 }
23 
24 void manacher(char s[])
25 {
26     int id, mx = 0;
27     p[0] = 0;
28     for(int i = 1; s[i] != '\0'; ++i)
29     {
30         if(mx > i)
31             p[i] = min(p[2*id-i], mx - i);
32         else
33             p[i] = 1;
34         while(s[i+p[i]] == s[i-p[i]])
35             ++p[i];
36         if(i + p[i] > mx)
37         {
38             mx = i + p[i];
39             id = i;
40         }
41     }
42 }
43 
44 void getans(void)
45 {
46     int ans = 0;
47     for(int i = 1; s2[i] != '\0'; ++i)
48         ans = max(ans, p[i] - 1);
49     printf("%d\n", ans);
50 }
51 
52 int main(void)
53 {
54     #ifdef LOCAL
55         freopen("3068in.txt", "r", stdin);
56     #endif
57 
58     while(scanf("%s", s1) != EOF)
59     {
60         init(s1, s2);
61         manacher(s2);
62         getans();
63     }
64     return 0;
65 }
代码君