Palindrome(最长回文串manacher算法)O(n)

Palindrome

Time Limit:15000MS     Memory Limit:65536KB     64bit IO Format:%I64d & %I64u

Submit Status

Description

Andy the smart computer science student was attending an algorithms class when the professor asked the students a simple question, "Can you propose an efficient algorithm to find the length of the largest palindrome in a string?"

A string is said to be a palindrome if it reads the same both forwards and backwards, for example "madam" is a palindrome while "acm" is not.

The students recognized that this is a classical problem but couldn‘t come up with a solution better than iterating over all substrings and checking whether they are palindrome or not, obviously this algorithm is not efficient at all, after a while Andy raised his hand and said "Okay, I‘ve a better algorithm" and before he starts to explain his idea he stopped for a moment and then said "Well, I‘ve an even better algorithm!".

If you think you know Andy‘s final solution then prove it! Given a string of at most 1000000 characters find and print the length of the largest palindrome inside this string.

Input

Your program will be tested on at most 30 test cases, each test case is given as a string of at most 1000000 lowercase characters on a line by itself. The input is terminated by a line that starts with the string "END" (quotes for clarity).

Output

For each test case in the input print the test case number and the length of the largest palindrome.

Sample Input

abcbabcbabcba
abacacbaaaab
END

Sample Output

Case 1: 13
Case 2: 6
 1 #include<cstdio>
 2 #include<cstring>
 3 #include<cstdlib>
 4 #include<algorithm>
 5 using namespace std;
 6 const int maxn=1000000+10;
 7 //manacher算法
 8 const int LEN=maxn;
 9 const int N=LEN*2;
10 int p[N];
11 char str[LEN],tmp[N];
12 //p[i]表示以str[i]为中心的回文往右延伸的 最长长度
13 void manacher(char* str, int* p)
14 {
15     int n=strlen(str), i, id, mx;
16     for(p[mx=id=0]=i=1; i<n; i++)
17     {
18         p[i]=mx>i?min(p[2*id-i], mx-i+1):1;
19         while(i+p[i]<n&&i-p[i]>=0&&str[i+p[i]]==str[i-p[i]]) p[i]++;
20         if(mx<i+p[i]-1)
21         {
22             id=i;
23             mx=i+p[i]-1;
24         }
25     }
26 }
27 //求str的最长回文的长度
28 int maxPalindrome(char* str)
29 {
30     int ans=0;
31     int i, n;
32     for(i=0, n=strlen(str); i<n; i++)
33     {
34         tmp[2*i]=‘#‘;
35         tmp[2*i+1]=str[i];
36     }
37     tmp[2*i]=‘#‘;
38     tmp[2*i+1]=‘\0‘;
39     n=n*2+1;
40     manacher(tmp, p);
41     for(i=0; i<n; i++)
42     {
43         if(ans < p[i]-1)
44         {
45             ans = p[i]-1;
46         }
47     }
48     return ans;
49 }
50 int main()
51 {
52     int i=1;
53     for(i=1;; i++)
54     {
55         scanf("%s",str);
56         char s[]= {‘E‘,‘N‘,‘D‘,‘\0‘};
57         if(strcmp(str,s)==0)
58             break;
59         else
60             printf("Case %d: %d\n",i,maxPalindrome(str));
61     }
62     return 0;
63 }
时间: 2024-10-07 11:26:10

Palindrome(最长回文串manacher算法)O(n)的相关文章

hiho#1032 : 最长回文子串 (manacher算法O(n)时间求字符串的最长回文子串 )

#1032 : 最长回文子串 时间限制:1000ms 单点时限:1000ms 内存限制:64MB 描述 小Hi和小Ho是一对好朋友,出生在信息化社会的他们对编程产生了莫大的兴趣,他们约定好互相帮助,在编程的学习道路上一同前进. 这一天,他们遇到了一连串的字符串,于是小Hi就向小Ho提出了那个经典的问题:"小Ho,你能不能分别在这些字符串中找到它们每一个的最长回文子串呢?" 小Ho奇怪的问道:"什么叫做最长回文子串呢?" 小Hi回答道:"一个字符串中连续的一

Hdu 3068 最长回文字串Manacher算法

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

HiHo 1032 最长回文子串 (Manacher算法求解)

Manacher算法o(n)求解最长回文子串问题 非常巧妙 #include<bits/stdc++.h> using namespace std; char str[2000020],s[2000020]; int p[2000020]; int len,id,mx; void pre() //对字符串进行预处理 { len=strlen(s); str[0]='$'; str[1]='#'; for(int i=0;i<len;i++) { str[i*2+2]=s[i]; str[

最长回文---hdu3068 (回文串 manacher 算法模板)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3068 题意很清楚:就是求一个串s的子串中最长回文串的长度:这类题用到了manacher算法 manacher算法(复制大神的解释): 定义数组p[i]表示以i为中心的(包含i这个字符)回文串半径长 将字符串s从前扫到后for(int i=0;i<strlen(s);++i)来计算p[i],则最大的p[i]就是最长回文串长度,则问题是如何去求p[i]? 由于s是从前扫到后的,所以需要计算p[i]时一定

1112个人赛,最长回文串常见算法讨论

ps.此贴大部分文字与代码来自网上,我只是取长补短整理了下 S=“c a b a”  那么  S' = “a b a c”, 这样的情况下 S和 S‘的最长公共子串是aba.没有错误. 但是当 S=“abacdfgdcaba”, 那么S’ = “abacdgfdcaba”. 这样S和S‘的最长公共子串是abacd.很明显abacd并不是S的最长回文子串,它甚至连回文都不是. 现在是不是都明白为什么最长回文子串不能转化成为最长公共子串问题了.当原串S中含有一个非回文的串的反序串的时候,最长公共子串

hdu-3068 最长回文 【Manacher算法】

Manacher算法学习资料:http://blog.csdn.net/dyx404514/article/details/42061017 最长回文 Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 9282    Accepted Submission(s): 3194 Problem Description 给出一个只由小写英文字符

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算法模板)

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: a

【最长回文子串】HDU3068最长回文【Manacher算法】

一张图领悟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之间由空行隔开(该空行不用处理)