Palindrome POJ - 3974(最长回文 Manacher算法)

题:
聪明的计算机科学学生安迪正在上算法课,教授问学生一个简单的问题,“你能提出一个有效的算法来找出字符串中最大回文的长度吗?”
如果一个字符串向前和向后读都是相同的,那么它就被称为回文。例如,“madam”是回文,“acm”不是。
学生们认识到这是一个经典的问题,但是他们无法找到一个比遍历所有子串并检查它们是否是回文的更好的解决方案,显然这个算法根本没有效率,过了一会儿,安迪举起手说:“好吧,我有更好的在他开始解释他的想法之前,他停了一下,然后说:“好吧,我有一个更好的算法!”.
如果你认为你知道安迪的最终解决方案,那就证明它!如果字符串最多为1000000个字符,则查找并打印该字符串中最大回文的长度。
输入
您的程序最多将在30个测试用例上进行测试,每个测试用例本身就以一行最多1000000个小写字符的字符串形式给出。输入被以字符串“end”开头的行终止(为清晰起见,用引号引起来)。
输出
对于输入中的每个测试用例,打印测试用例编号和最大回文的长度。
Sample Input
abcbabcbabcba
abacacbaaaab
END
Sample Output
Case 1: 13
Case 2: 6
题解:
一道最长回文的模板题:

#include<iostream>
#include<algorithm>
#include<string.h>
#include<cstring>
#include <stdio.h>
char s[2200100],a[1100050];
int len,pos,p[2200100],ans,r;
using namespace std;
void add()
{
    s[0]='A';
    int i=1,j=0;
    while(i<2*len+1)
    {
        s[i++]='#';
        s[i++]=a[j++];
    }
    s[i++]='#';
    len=2*len+2;
}
int Manacher()
{
    ans=r=pos=0;
    for(int i=0;i<len;i++)
    {
        if(i<r)
            p[i]=min(p[2*pos-i],r-i);
        else
            p[i]=1;
        while(s[i+p[i]]==s[i-p[i]])
            p[i]++;
        if(i+p[i]>r)
        {
            r=i+p[i];
            pos=i;
        }
        ans=max(ans,p[i]-1);

    }
    return ans;
}
int main()
{
    int i=0;
   while(scanf("%s",a))
   {
       if(strcmp(a,"END")==0)
       {
           break;
       }
       i++;
       len=strlen(a);
       add();
       ans=Manacher();
       cout<<"Case "<<i<<": ";
       cout<<ans<<endl;
   }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值