POJ (Manacher) Palindrome

多敲几个模板题,加深一下对Manacher算法的理解。

这道题给的时间限制15s,是我见过的最长的时间的了。看来是为了让一些比较朴素的求最大回文子串的算法也能A过去

Manacher算法毕竟给力,运行时间200+MS

 1 //#define LOCAL
 2 #include <iostream>
 3 #include <cstdio>
 4 #include <cstring>
 5 #include <algorithm>
 6 using namespace std;
 7
 8 const int maxn = 1000000 + 100;
 9 char s1[maxn], s2[maxn * 2];
10 int p[maxn * 2];
11
12 void Init(void)
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[id*2-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 int getans(void)
45 {
46     int ans = 1;
47     for(int i = 1; s2[i] != ‘\0‘; ++i)
48         ans = max(ans, p[i] - 1);
49     return ans;
50 }
51
52 int main(void)
53 {
54     #ifdef LOCAL
55         freopen("3974in.txt", "r", stdin);
56     #endif
57
58     int kase = 1;
59     while(scanf("%s", s1) != EOF)
60     {
61         if(s1[0] == ‘E‘)    break;
62         Init();
63         manacher(s2);
64         printf("Case %d: %d\n", kase++, getans());
65     }
66     return 0;
67 }

代码君

POJ (Manacher) Palindrome,布布扣,bubuko.com

时间: 2024-10-07 07:30:57

POJ (Manacher) Palindrome的相关文章

POJ 3974 Palindrome Manacher算法题解

本题就是求最长的回文子串. 字符串超长,不过限时却是也很长的15秒,最长的限时之一题目了,如果限时短点的话,估计能过的人不多. 使用Mancher算法是可以秒杀的. 模板式的Manacher算法: #include <stdio.h> #include <vector> #include <string.h> #include <algorithm> #include <iostream> #include <string> #inc

POJ 1159 Palindrome 题解

本题的题意理解之后,就是求最长回文子序列 longest palindrome subsequence,这里注意子序列和子串的区别. 有两种求法,一种是直接求,相当于填矩阵右上对角阵,另一种是转化为longest common subsequence的求法. 最大难点就是要求内存不能使用二维的. 故此第一种方法是有点难度的,因为需要把二维矩阵的对角线转化为一维表记录,对好下标就好了. 第二中方法会稍微容易点,效率都是一样的O(n*n). 方法1: #include <cstdio> const

POJ 1159 Palindrome

Palindrome Time Limit: 3000MS   Memory Limit: 65536K Total Submissions: 51518   Accepted: 17733 Description A palindrome is a symmetrical string, that is, a string read identically from left to right as well as from right to left. You are to write a

POJ 1159 Palindrome &amp;&amp; HDU 1159 Common Subsequence

1.先说说杭电的1159吧! 这道题是基础动规,比较简单! 就是要你求最长的公共子序列(不要优化) 动态转移方程: dp[i+1][j+1]=(a[i]=b[i])?dp[i][j]+1:max(dp[i+1][j],dp[i][j+1]) AC代码: #include<stdio.h> #include<string.h> #include<algorithm> using namespace std; #define N 520 char a[N],b[N]; in

LCS POJ 1159 Palindrome

题目传送门 1 /* 2 LCS裸题:长度减去最大相同长度就是要插入的个数 3 */ 4 #include <cstdio> 5 #include <iostream> 6 #include <cstring> 7 #include <algorithm> 8 #include <string> 9 using namespace std; 10 11 const int MAXN = 5e3 + 10; 12 const int INF = 0

poj 1156 Palindrome

Palindrome Time Limit: 3000MS   Memory Limit: 65536K Total Submissions: 51631   Accepted: 17768 Description A palindrome is a symmetrical string, that is, a string read identically from left to right as well as from right to left. You are to write a

LCS(滚动数组) POJ 1159 Palindrome

题目传送门 1 /* 2 LCS裸题:长度减去最大相同长度就是要插入的个数 3 dp数组二维都开5000的话就会超内存,这里就用到了滚动数组, 4 因为在LCS的计算中,i的变化只相差1,所以可以通过对2取余来进行滚动:) 5 */ 6 #include <cstdio> 7 #include <iostream> 8 #include <cstring> 9 #include <algorithm> 10 #include <string> 1

poj 1159 Palindrome lcs+滚动数组

点击打开链接题目链接 Palindrome Time Limit: 3000MS   Memory Limit: 65536K Total Submissions: 52910   Accepted: 18248 Description A palindrome is a symmetrical string, that is, a string read identically from left to right as well as from right to left. You are

poj 1159 Palindrome (LCS)

链接:poj 1159 题意:给定一个字符串,求最少添加多少个字符可使得该字符串变为回文字符串 分析:设原序列S的逆序列为S' ,最少需要补充的字母数 = 原序列S的长度 - S和S'的最长公共子串长度 原因:要求最少添加几个字符,我们可以先从原串中找到一个最长回文串,然后对于原串中不属于这个回文串的字符,在它关于回文串中心的对称位置添加一个相同字符即可.那么需要添加的字符数量即为n-最长回文串长度. 最长回文串可以看作是原串中前面和后面字符的一种匹配(每个后面的字符在前面找到一个符合位置要求的