POJ3974 Palindrome (manacher算法)

题目大意就是说在给定的字符串里找出一个长度最大的回文子串。

才开始接触到manacher,不过这个算法的确很强大,这里转载了一篇有关manacher算法的讲解,可以去看看:地址

神器:

 1 #include <map>
 2 #include <set>
 3 #include <stack>
 4 #include <queue>
 5 #include <cmath>
 6 #include <ctime>
 7 #include <vector>
 8 #include <cstdio>
 9 #include <cctype>
10 #include <cstring>
11 #include <cstdlib>
12 #include <iostream>
13 #include <algorithm>
14 using namespace std;
15 #define INF 0x3f3f3f3f
16 #define inf (-((LL)1<<40))
17 #define lson k<<1, L, mid
18 #define rson k<<1|1, mid+1, R
19 #define mem0(a) memset(a,0,sizeof(a))
20 #define mem1(a) memset(a,-1,sizeof(a))
21 #define mem(a, b) memset(a, b, sizeof(a))
22 #define FOPENIN(IN) freopen(IN, "r", stdin)
23 #define FOPENOUT(OUT) freopen(OUT, "w", stdout)
24 
25 template<class T> T CMP_MIN(T a, T b) { return a < b; }
26 template<class T> T CMP_MAX(T a, T b) { return a > b; }
27 template<class T> T MAX(T a, T b) { return a > b ? a : b; }
28 template<class T> T MIN(T a, T b) { return a < b ? a : b; }
29 template<class T> T GCD(T a, T b) { return b ? GCD(b, a%b) : a; }
30 template<class T> T LCM(T a, T b) { return a / GCD(a,b) * b;    }
31 
32 //typedef __int64 LL;
33 typedef long long LL;
34 const int MAXN = 4000000+10;
35 const int MAXM = 2000010;
36 const double eps = 1e-12;
37 
38 char str[MAXN];
39 int rad[MAXN];
40 
41 int manacher()
42 {
43     mem0(rad);
44     for(int i=1,j=0,k,len=strlen(str)<<1;i<len;)
45     {
46         while (str[i-j-1]==str[i+j+1]) j++;  //扫描得出rad值
47         rad[i]=j;
48         for (k=1; k<=j && rad[i-k]!=rad[i]-k; k++) rad[i+k]=min(rad[i-k],rad[i]-k);  //k指针扫描
49         i+=k;  //i跳到下一个需要计算rad值的位置
50         j=max(j-k,0);  //更新下一个rad值的初始值
51     }
52     int ans = 0;
53     for(int i=1;i<strlen(str);i++)
54     {
55         int x ;
56         if(str[i] != '#') x = rad[i]/2*2+1;
57         else x = (rad[i]+1)/2*2;
58         ans = max(ans, x);
59     }
60     return ans;
61 }
62 
63 int main()
64 {
65     int T = 0;
66     while(gets(str)!=NULL && str[0] != 'E')
67     {
68         int len = strlen(str);
69         for(int i=len-1;i>=0;i--)
70         {
71             str[(i<<1)+2] = '#';
72             str[(i<<1)+1] = str[i];
73         }
74         str[0] = '?'; str[len<<1] = '*';
75         //printf("%s\n", str);
76         int ans = manacher();
77         printf("Case %d: %d\n", ++T, ans);
78         mem0(str);
79     }
80     return 0;
81 }

 

posted @ 2014-03-25 12:59  再见~雨泉  阅读(214)  评论(0编辑  收藏  举报