【HDOJ】3068 最长回文

马拉车算法O(n)可解。

 1 /* 3068 */
 2 #include <iostream>
 3 #include <string>
 4 #include <map>
 5 #include <queue>
 6 #include <set>
 7 #include <stack>
 8 #include <vector>
 9 #include <deque>
10 #include <algorithm>
11 #include <cstdio>
12 #include <cmath>
13 #include <ctime>
14 #include <cstring>
15 #include <climits>
16 #include <cctype>
17 #include <cassert>
18 #include <functional>
19 using namespace std;
20 //#pragma comment(linker,"/STACK:102400000,1024000")
21
22 #define sti                set<int>
23 #define stpii            set<pair<int, int> >
24 #define mpii            map<int,int>
25 #define vi                vector<int>
26 #define pii                pair<int,int>
27 #define vpii            vector<pair<int,int> >
28 #define rep(i, a, n)     for (int i=a;i<n;++i)
29 #define per(i, a, n)     for (int i=n-1;i>=a;--i)
30 #define clr                clear
31 #define pb                 push_back
32 #define mp                 make_pair
33 #define fir                first
34 #define sec                second
35 #define all(x)             (x).begin(),(x).end()
36 #define SZ(x)             ((int)(x).size())
37 #define lson            l, mid, rt<<1
38 #define rson            mid+1, r, rt<<1|1
39
40 const int maxn = 110005;
41 char s[maxn*2], ss[maxn];
42 int P[maxn*2];
43 int ans, l;
44
45 void init() {
46     int i, len = strlen(ss);
47
48     l = 0;
49     s[l++] = ‘@‘;
50     s[l++] = ‘#‘;
51     for (i=0; i<len; ++i) {
52         s[l++] = ss[i];
53         s[l++] = ‘#‘;
54     }
55     s[l++] = ‘\0‘;
56 }
57
58 void manacher() {
59     int i, mx = 0, id;
60
61     for (i=1; i<l; ++i) {
62         P[i] = mx>i ? min(P[2*id-i], mx-i) : 1;
63         while (s[i+P[i]] == s[i-P[i]])
64             ++P[i];
65         if (i+P[i] > mx) {
66             mx = i + P[i];
67             id = i;
68         }
69     }
70
71     ans = 0;
72     for (i=1; i<l; ++i)
73         ans = max(ans, P[i]);
74     printf("%d\n", ans-1);
75 }
76
77 void solve() {
78     init();
79     manacher();
80 }
81
82 int main() {
83     ios::sync_with_stdio(false);
84     #ifndef ONLINE_JUDGE
85         freopen("data.in", "r", stdin);
86         freopen("data.out", "w", stdout);
87     #endif
88
89     while (scanf("%s", ss)!=EOF) {
90         solve();
91     }
92
93     #ifndef ONLINE_JUDGE
94         printf("time = %d.\n", (int)clock());
95     #endif
96
97     return 0;
98 }
时间: 2024-11-05 17:47:35

【HDOJ】3068 最长回文的相关文章

Manacher HDOJ 3068 最长回文

题目传送门 关于求解最长回文子串,有dp做法,也有同样n^2的但只用O(1)的空间,还有KMP,后缀数组?? 1 int main(void) { 2 while (scanf ("%s", str + 1) == 1) { 3 int len = strlen (str + 1); 4 memset (dp, false, sizeof (dp)); 5 for (int i=1; i<=len; ++i) dp[i][i] = true; 6 for (int i=1; i&

hdoj 3068 最长回文 【manacher算法】

题意... 用传统的方法来做的话,要超时(就是要进行奇偶判断). manacher算法,百度一下讲解好的有很多. 纪念粘代码: #include <stdio.h> #include <string.h> #include <algorithm> using namespace std; #define M 110010 char a[M], b[M<<1]; int p[M<<1]; int main(){ while(~scanf("

hdu 3068 最长回文(manacher&amp;最长回文子串)

最长回文 Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 7317    Accepted Submission(s): 2500 Problem Description 给出一个只由小写英文字符a,b,c...y,z组成的字符串S,求S中最长回文串的长度. 回文就是正反读都是一样的字符串,如aba, abba等 Input 输入有多组

HDU 3068 最长回文 (manacher算法)

最长回文 Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 9188    Accepted Submission(s): 3159 Problem Description 给出一个只由小写英文字符a,b,c...y,z组成的字符串S,求S中最长回文串的长度. 回文就是正反读都是一样的字符串,如aba, abba等 Input 输入有多组

HDU 3068(最长回文-manacher)[Template:manacher]

最长回文 Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 9660    Accepted Submission(s): 3353 Problem Description 给出一个只由小写英文字符a,b,c...y,z组成的字符串S,求S中最长回文串的长度. 回文就是正反读都是一样的字符串,如aba, abba等 Input 输入有多组

HDU 3068 最长回文(manacher算法)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3068 Problem Description 给出一个只由小写英文字符a,b,c...y,z组成的字符串S,求S中最长回文串的长度. 回文就是正反读都是一样的字符串,如aba, abba等 Input 输入有多组case,不超过120组,每组输入为一行小写英文字符a,b,c...y,z组成的字符串S 两组case之间由空行隔开(该空行不用处理) 字符串长度len <= 110000 Output 每

HDU 3068 最长回文

最长回文串模板题 Manacher 算法 1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 #include<iostream> 5 #include<cstdlib> 6 #include<string> 7 #include<cmath> 8 #include<vector> 9 using namespace std; 10 co

HDU - 3068 最长回文(manacher算法)

题意:给出一个只由小写英文字符a,b,c...y,z组成的字符串S,求S中最长回文串的长度. 分析: manacher算法: 1.将字符串中每个字符的两边都插入一个特殊字符.(此操作的目的是,将字符串长度统一变成奇数,道理很容易想---奇数+偶数=奇数or偶数+奇数=奇数) eg:abba--->#a#b#b#a# 此外,为了便于处理边界,可在字符串开始处再加另外一个特殊字符. eg:#a#b#b#a#--->$#a#b#b#a# 2.数组 P[i] 来记录以字符S[i]为中心的最长回文子串向

HDU 3068 最长回文(初遇manacher)

这题可用拓展KMP分治法来做http://blog.sina.cn/dpool/blog/s/blog_677a3eb30100knj8.html 复杂度O(nlogn)这种方法好复杂而且代码很长,不易理解. 相比之下Manacher就简单多了,算法本身也很简单 这里个易懂的资料http://wenku.baidu.com/view/3031d2d3360cba1aa811da42.html 复杂度O(n) kuangbin的模版(有一处修改) /* * 求最长回文子串 */ const int

HDU 3068 最长回文(Manacher)

题目链接:[kuangbin带你飞]专题十六 KMP & 扩展KMP & Manacher 题意 给出一个只由小写英文字符a,b,c-y,z组成的字符串S,求S中最长回文串的长度. 回文就是正反读都是一样的字符串,如aba, abba等 思路 用特殊字符插入到s串中每两个字符中间,实现每个回文串都是奇数,再用manacher算法进行求解. 代码 #include <iostream> #include <algorithm> #include <cstring