poj3974 最长回文串 exkmp

Palindrome

Time Limit: 15000MS   Memory Limit: 65536K
Total Submissions: 3695   Accepted: 1338

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

题意:求最长回文子串

解法:当然,有很多种求法,什么SA,什么manacher,介于我最近在搞扩展kmp,就发个扩展kmp的吧。

讲解网址(不是我写的)http://hi.baidu.com/tcet030840zxp/item/71fd90024b1f92cd90571809
#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<cmath>
#include<cstring>

using namespace std;

int s[1000111];
int s1[1000111],s2[1000111],s3[1000111],s4[1000111];
int a[1000111],b[1000111],exEast[1000111],exWest[1000111];
int n,xzq,t;
char c;
bool p;

void Read()
{
    n=0;
    while(c=getchar(),(c<‘a‘||c>‘z‘)&&(c<‘A‘||c>‘Z‘));
    if(c==‘E‘)p=false;
    s[++n]=c;
    while(c=getchar(),c>=‘a‘&&c<=‘z‘)s[++n]=c;
}

void Exkmp(int *s1,int *s2,int n1,int n2)
{
    int len,k,i,l;
    len=0;
    for(i=2;i<=n1;i++){
        if(len<i){
            l=0;
            while(s1[i+l]==s1[1+l]&&i+l<=n1)l++;
            a[i]=l;
        }
        else{
            if(a[i-k+1]<len-i+1)a[i]=a[i-k+1];
            else{
                l=len-i+1;
                while(s1[i+l]==s1[1+l]&&i+l<=n1)l++;
                a[i]=l;
            }
        }
        if(i+a[i]-1>len){
            len=i+a[i]-1;
            k=i;
        }
    }
    len=0;
    for(i=1;i<=n2;i++){
        if(len<i){
            l=0;
            while(s2[i+l]==s1[1+l]&&i+l<=n2&&1+l<=n1)l++;
            b[i]=l;
        }
        else{
            if(a[i-k+1]<len-i+1)b[i]=a[i-k+1];
            else{
                l=len-i+1;
                while(s2[i+l]==s1[1+l]&&i+l<=n2&&1+l<=n1)l++;
                b[i]=l;
            }
        }
        if(i+b[i]-1>len){
            len=i+b[i]-1;
            k=i;
        }
    }
}

int Work(int l,int r)
{
    if(l==r)return 1;
    int mid=(l+r)/2;
    int x,z,q,i,n1,n2,k;
    x=0;
    z=0;
    q=0;
    x=Work(l,mid);
    z=Work(mid+1,r);
    if(x>z)q=x;
    else q=z;
    n1=mid-l+1;
    for(i=l;i<=mid;i++){
        k=i-l+1;
        s1[k]=s[i];
        s3[n1-k+1]=s1[k];
    }
    n2=r-mid;
    for(i=mid+1;i<=r;i++){
        k=i-mid;
        s2[k]=s[i];
        s4[n2-k+1]=s2[k];
    }
    Exkmp(s3,s1,n1,n1);
    for(i=1;i<=n1;i++)exEast[i]=b[i];
    Exkmp(s2,s3,n2,n1);
    for(i=1;i<=n1;i++)exWest[n1-i+1]=b[i];
    exWest[0]=0;
    if(exWest[n1]*2>q)q=exWest[n1]*2;
    for(i=1;i<=n1;i++){
        if(exEast[i]*2>=n1-i+1){
            if(n1-i+1+exWest[i-1]*2>q)q=n1-i+1+exWest[i-1]*2;
        }
    }
    Exkmp(s3,s2,n1,n2);
    for(i=1;i<=n2;i++)exEast[i]=b[i];
    Exkmp(s2,s4,n2,n2);
    for(i=1;i<=n2;i++)exWest[n2-i+1]=b[i];
    if(exEast[1]*2>q)q=exEast[1]*2;
    exEast[n2+1]=0;
    for(i=1;i<=n2;i++){
        if(exWest[i]*2>=i){
            if(i+exEast[i+1]*2>q)q=i+exEast[i+1]*2;
        }
    }
    return q;
}

int main()
{
    p=true;
    t=0;
    while(true){
        t++;
        memset(s,0,sizeof(s));
        Read();
        if(p==false)break;
        xzq=Work(1,n);
        printf("Case %d: %d\n",t,xzq);
    }
}

poj3974 最长回文串 exkmp

时间: 2024-09-27 07:02:51

poj3974 最长回文串 exkmp的相关文章

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) {

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 最长回文串(manachar模板)

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

(最长回文串 模板) 最长回文 -- hdu -- 3068

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): 12079    Accepted Submission(s): 4430 Problem Description 给出一个只由小写英文字符a,b,c...y,z组成的字符串S,求S中最长

hdu 3068 最长回文串 o(n) Manacher 算法

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

HDU ACM 4513 吉哥系列故事——完美队形II-&gt;求最长回文串(manacher算法)

分析:该題可以通过求最长回文串的方法来解决:求最长回文串使用manacher算法,O(n)时间复杂度. 注意:while(a[i-len[i]]==a[i+len[i]] && a[i-len[i]]<=a[i-len[i]+2])这里多出的判断a[i-len[i]]<=a[i-len[i]+2]即为该題的限制从左到中保证身高不降,因在回文串的计算过程中添加了额外的字符,所以这里是i-len[i]+2而不是i-len[i]+1,以避开添加的字符. #include<ios

Manacher算法 O(n)求最长回文串

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

Manacher算法 最长回文串

Manacher算法O(n) 因为对于偶回文,是需要从虚轴扩充,ab,ba,所以如下: 先把原字符串处理,都加上一个标记符,比如#(特殊字符任何都可以,对于计算结果不会有影响) 1221-->#1#2#2#1# 121-->#1#2#1# 按照处理后的字符串求它的最长回文串长度m,所以原始字符串最长子回文串的长度是m/2 变量: 1:PArra[] 存放回文半径:某个位置能扩充的回文半径的长度,例如 #1#2#2#1#,2位置PArra[3] = 4 2:int PR 能够扫到的最右的回文的位

Hdu 3294 Girls&#39; research (manacher 最长回文串)

题目链接: Hdu 3294  Girls' research 题目描述: 给出一串字符串代表暗码,暗码字符是通过明码循环移位得到的,比如给定b,就有b == a,c == b,d == c,.......,a == z. 问最长回文串所在区间,以及最长回文串所表示的明码. 解题思路: 字符串长度[1,200000],用manacher算法很轻松就搞定了. get√新技能请点击me 1 #include <cstdio> 2 #include <cstring> 3 #includ