本文版权归ljh2000和博客园共有,欢迎转载,但须保留此声明,并给出原文链接,谢谢合作。

本文作者:ljh2000
作者博客:http://www.cnblogs.com/ljh2000-jump/
转载请注明出处,侵权必究,保留最终解释权!

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

正解:manacher

解题报告:

  manacher模板题。

  网上有一篇博客写得很清楚:https://segmentfault.com/a/1190000003914228。

  大致做法就是:维护一个目前所接触的最右端(不妨设为$maxRight$),和使得最长回文子串取到最右端的对称中心位置(不妨设为$id$),我们需要对于每个i求$p[i]$,$p[i]$表示以$i$为中心的最长回文串半径(包括$i$自身)。

  每次处理i时,分类讨论:

  如果$i>=maxRight$,显然$i$只能重新开始拓展,不能利用前面的结果,暴力比较即可;

  如果$i<maxRight$,又可以分两种情况讨论,那篇博客里面说的很清楚了,分为$p[j]$很长和$p[j]$很短两种情况——总之就是可以利用之前的对于现在的$p[i]$确定一个初值,即$p[i]=min(p[2*id-i],maxRight-i)$。

  容易发现最后$max(p[i]-1)$就是我们想求的答案。

//It is made by ljh2000
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <algorithm>
using namespace std;
typedef long long LL;
const int MAXN = 2000011;
const int MAXM = 1000011;
int len,n,p[MAXN],Case,ans,id,maxRight;
char ch[MAXM],s[MAXN]; inline int getint(){
int w=0,q=0; char c=getchar(); while((c<'0'||c>'9') && c!='-') c=getchar();
if(c=='-') q=1,c=getchar(); while (c>='0'&&c<='9') w=w*10+c-'0',c=getchar(); return q?-w:w;
} inline void manacher(){
s[0]='%'; s[1]='#'; n=1;
for(int i=0;i<len;i++) {
s[++n]=ch[i];
s[++n]='#';//插入字符,化偶为奇
}
maxRight=0; id=0;
for(int i=1;i<=n;i++) {
//p[i]表示以i为中心的最长回文串半径(包括i)
if(i<maxRight) p[i]=min(p[2*id-i],maxRight-i); else p[i]=1;
for(;i+p[i]<=n && s[i-p[i]]==s[i+p[i]];p[i]++) ;
if(i+p[i]>maxRight) { id=i; maxRight=i+p[i]; }
}
for(int i=1;i<=n;i++) ans=max(ans,p[i]);
ans--;
} inline void work(){
while(scanf("%s",ch)!=EOF) {
len=strlen(ch); if(len==3 && ch[0]=='E' && ch[1]=='N' && ch[2]=='D') break;
memset(p,0,sizeof(p)); ans=1;
manacher(); Case++;
printf("Case %d: %d\n",Case,ans);
}
} int main()
{
work();
return 0;
}

  

POJ3974 Palindrome的更多相关文章

  1. POJ----(3974 )Palindrome [最长回文串]

    Time Limit: 15000MS   Memory Limit: 65536K Total Submissions: 5121   Accepted: 1834 Description Andy ...

  2. poj3974 Palindrome【回文】【Hash】【二分】

    Palindrome Time Limit: 15000MS   Memory Limit: 65536K Total Submissions: 13157   Accepted: 5028 Desc ...

  3. POJ3974 Palindrome (manacher算法)

    题目大意就是说在给定的字符串里找出一个长度最大的回文子串. 才开始接触到manacher,不过这个算法的确很强大,这里转载了一篇有关manacher算法的讲解,可以去看看:地址 神器: #includ ...

  4. POJ--3974 Palindrome(回文串,hash)

    链接:点击这里 #include<iostream> #include<algorithm> #include<stdio.h> #include<cstri ...

  5. 【Manacher算法】poj3974 Palindrome

    Manacher算法教程:http://blog.csdn.net/ggggiqnypgjg/article/details/6645824 模板题,Code 附带注释: #include<cs ...

  6. 【后缀数组】【线段树】poj3974 Palindrome

    考虑奇数长度的回文,对于字符串上的每个位置i,如果知道从i开始的后缀和到i为止的前缀反转后的字符串的lcp长度的话,也就知道了以第i个字符为对称中心的最长回文的长度了.因此,我们用在S中不会出现的字符 ...

  7. POJ3974 Palindrome Manacher 最长回文子串模板

    这道题可以$O(nlogn)$,当然也可以$O(n)$做啦$qwq$ $O(nlogn)$的思路是枚举每个回文中心,通过哈希预处理出前缀和后缀哈希值备用,然后二分回文串的长度,具体的就是判断在长度范围 ...

  8. [POJ3974]Palindrome(后缀数组 || manacher)

    传送门 求一个串的最长回文子串的长度 1.后缀数组 把这个串反转后接到原串的后面,中间连一个没有出现过的字符. 然后求这个新字符串的某两个后缀的公共前缀的最大值即可. ——代码 #include &l ...

  9. [poj3974] Palindrome 解题报告 (hash\manacher)

    题目链接:http://poj.org/problem?id=3974 题目: 多组询问,每组给出一个字符串,求该字符串最长回文串的长度 数据范围支持$O(nlog n)$ 解法一: 二分+hash ...

随机推荐

  1. U制作LFS linux

    我希望自己的LFS运行在U盘上,远期目标是要制作一个基于LFS的编程练习U盘,方便自己的编程练习.今天算是工作的第一步,先把LFS做到U盘上. 把Linux做到U盘上通常的做法是采用两步启动法:先生成 ...

  2. Linux下的nginx启动、重新启动

    nginx的启动命令是: /usr/local/nginx/sbin/nginx -c /usr/local/nginx/conf/nginx.conf -c制定配置文件的路径,不加-nginx会自动 ...

  3. HW5.18

    public class Solution { public static void main(String[] args) { System.out.printf("%s\t%s\n&qu ...

  4. log4j输出信息到mongodb

    官网     http://log4mongo.org/display/PUB/Log4mongo+for+Java 保存主机信息,方法等      http://my.oschina.net/chi ...

  5. [六]JFreeChart实践五之与Struts2整合

    1.Action,返回Chart package com.java1234.chart.bar; import java.awt.Color; import org.jfree.chart.Chart ...

  6. JS多态

    面向对象语言有三大特征,前面介绍了封装和继承,那么JS作为一门面向对象语言,有多态么,又怎么实现多态呢? 我们先看看多态的概念: 多态:同一操作作用于不同的对象,可以有不同的解释,产生不同的执行结果. ...

  7. oc学习之路----QQ聊天界面

    用到的技术:自定义cell,通知机制,代理模式 transform 1.自定义cell(通过代码自定义cell) ①首先新建一个类继承UITableViewCell ②重写initWithStyle: ...

  8. 读FCL源码系列之List<T>---让你知其所以然---内含疑问求大神指点

    序言 在.NET开发中,List<T>是我们经常用到的类型.前段时间看到其他部门小伙伴讨论“两个List(10W个元素)集合求并集,list1.Where(p=>list2.Cont ...

  9. oracle 表空管理方式(LMT)、ASSM段管理方式、一级位图块、二级位图块、三级位图块。

    今天是2013-12-16,今天和明天是我学习oracle生涯中一个特殊的日子.今天晚上进行了一下表空间管理方式的学习,在此记录一下笔记. 对于oracle数据库最小i/0单位是数据块,最想分配空间单 ...

  10. IOS - view之间切换

    //进入下一页 - (IBAction)Go:(id)sender { TwoViewController *twoVC = [[TwoViewController alloc] init];//这里 ...