[HDOJ3068]最长回文

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3068

最长回文

Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 11870    Accepted Submission(s): 4351

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

Manacher算法的模版题,刚模仿着写了个,趁热用一下

 1 #include <cstdio>
 2 #include <cstdlib>
 3 #include <cstring>
 4 #include <algorithm>
 5 #include <iostream>
 6 #include <cmath>
 7 #include <queue>
 8 #include <map>
 9 #include <stack>
10 #include <list>
11 #include <vector>
12
13 using namespace std;
14
15 const int maxn = 1000010;
16 int pre[maxn];
17 char str[maxn];
18 char tmp[maxn*2];
19
20 inline int min(int x, int y) {
21     return x < y ? x : y;
22 }
23
24 int init(char *tmp, char *str) {
25     int len = strlen(str);
26     tmp[0] = ‘$‘;
27     for(int i = 0; i <= len; i++) {
28         tmp[2*i+1] = ‘#‘;
29         tmp[2*i+2] = str[i];
30     }
31     tmp[2*len+2] = 0;
32     len = 2 * len + 2;
33     return len;
34 }
35
36 void manacher(int *pre, char *tmp, int len) {
37     int id = 0;
38     int mx = 0;
39     for(int i = 1; i < len; i++) {
40         pre[i] = mx > i ? min(pre[2*id-i], mx-i) : 1;
41         while(tmp[i+pre[i]] == tmp[i-pre[i]]) {
42             pre[i]++;
43         }
44         if(pre[i] + i > mx) {
45             id = i;
46             mx = pre[i] + id;
47         }
48     }
49 }
50
51 int main() {
52     // freopen("in", "r", stdin);
53     while(~scanf("%s", str)) {
54         memset(pre, 0, sizeof(pre));
55         memset(tmp, 0, sizeof(tmp));
56         int len = init(tmp, str);
57         manacher(pre, tmp, len);
58         int ans = 1;
59         for(int i = 0; i < len; i++) {
60             ans = max(ans, pre[i]);
61         }
62         printf("%d\n", ans - 1);
63     }
64 }
时间: 2024-10-09 08:10:47

[HDOJ3068]最长回文的相关文章

HDOJ3068最长回文

最长回文 解法1.manacher算法 #include <cstdio> #include <cstring> #include <string> using namespace std; char str[1000002 + 1200]; int fast(char *p) { int ans = 1; for (int i = 1; p[i]; ++i) { int s = i, e = i, t; while (p[e + 1] == p[i]) ++e; i

【HDOJ3068】最长回文(manacher)

题意:求一个由小写字母组成的字符串中的最长回文长度 cas<=120 n<=110000 思路:试manacher板子 1 var a:array[0..300000]of char; 2 p:array[0..300000]of longint; 3 ch:ansistring; 4 len,n,i,mx,id,ans:longint; 5 6 function min(x,y:longint):longint; 7 begin 8 if x<y then exit(x); 9 exi

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 输入有多组

最长回文子序列

题目:给你一个字符串,求它的最长回文子序列,比如"bbbab" 最长回文子序列是"bbbb" 所以返回4,,"abab"最长子序列是"aba"或者"bab" 所以返回3 思路:和之前做的几道dp不同,,,也是我不够变通,,打dp表的时候总习惯左上到右下的顺序,但是这个顺序却固化了我的思维,忽略了对于题解本身含义的理解....... 这个题从下到上开始打表,最重要的是它的含义,,,知道dp[i][j]意味着什

最长回文算法2

问题: 求给定输入字符串的最长回文子序列(子序列不要求连续). 用LPS(i,j)表示从字符串第i个字符到第j个字符的最长回文子序列的长度,字符串的长度为n,则要求LPS(1,n),则: LPS(i,j)=0; i>j; LPS(i,j)=1; i==j; LPS(i,j)=LPS(i+1,j-1)+2; str[i]==str[j]; LPS(i,j)=max(LPS(i+1,j),LPS(i,j-1)); str[i]!=str[j]; // zuichanghuiwen2.cpp : 定义

409.求最长回文串的长度 LongestPalindrome

题目要求求出长度即可,并不需要求出最长回文串. 思路:用字典统计每一个字符的出现次数,出现次数大于1的字符必定出现在回文串中,另外还再加上一个中心点. public static int LongestPalindrome(string s) { int length = 0; Dictionary<char, int> dictionary = new Dictionary<char, int>(); int value = 0; foreach (char c in s) {

最长回文(hdu 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 每一行一个整数x,对应一组case,表示该组case的字符串中所包含的最长回文长度. Sample Inpu

《算法竞赛入门经典》3.3最长回文子串

1 //例题3-4 2 /* 3 * 输入一个字符串,求出其中最长的回文子串.子串的含义是:在原串中连续出现的字符串片段. 4 *回文的含义是:正看着和倒看着相同,如abba和yyxyy.在判断时,应该忽略所有标点符号和空格 5 *且忽略大小写,但输出应保持原样(在回文串的首部和尾部不要输出多余字符).输入字符长度不超过5000 6 *且占据单独的一行.应该输出最长回文串,如果有多个,输出起始位置最靠左的. 7 *样例输入:Confuciuss say:Madam,I'm Adam. 8 *样例

吉哥系列故事——完美队形II---hdu4513(最长回文子串manacher)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4513 题意比最长回文串就多了一个前面的人要比后面的人低这个条件,所以在p[i]++的时候判断一下s[i-p[i]]<=s[i-p[i]+2]就可以了; 用最长回文串算法manacher:套一下模板就可以了: #include<stdio.h> #include<string.h> #include<algorithm> using namespace std; con