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

先看代码:

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
#define maxx 101000
char s[maxx],s1[maxx*];
int mp[maxx*];
void Manacher(int l)
{
int k=;
s1[k++]='$';s1[k++]='#';
for(int i=;i<l;i++)
{
s1[k++]=s[i];
s1[k++]='#';
}
s1[k]=;
int mx=,id=;
for(int i=;i<k;i++)
{
mp[i]=mx>i?min(mp[*id-i],mx-i):;
while(s1[i+mp[i]]==s1[i-mp[i]])
mp[i]++;
if(i+mp[i]>mx)
{
mx=i+mp[i];
id=i;
}
}
}
int main()
{
while(~scanf("%s",s))
{
int l=strlen(s);
int ans=;
Manacher(l);
for(int i=;i<*l+;i++)
ans=max(ans,mp[i]-);
cout<<ans<<endl;
}
return ;
}

思路:

代码虽不长,主要需要理解的就是:

mp[i]=mx>i?min(mp[2*id-i],mx-i):1;

一般想法都是从1开始慢慢向两边移动来试探,而马拉车主要就是优化了每次试探P[i]的时候不一定需要从1开始,P[i]代表当前下标i为中心的字符串的回文串半径。

下图中 j 点代表是 i 关于 id 的对称点 ,j=2*id-i;

mx的对称点            j                 id                   i                 mx

id表示的就是最长回文串的中心,从图观察i与j关于Id对称,i是从2开始枚举过来已经经过了j的位置,那么j位置的最长回文串就可以确定了,如图所示;如果回文串完全被id的回文串所包围,那么根据对称原理i点的回文串的长度最少就是j点回文串的长度。即如果回文串的子串也是回文串,那么这个子串关于主串中心对称而得的子串也是一个回文串。接下来要确定的就是通过j点所能确定的i点回文串的长度最多是多少。首先应该明确,如果i点跑到mx(id点回文串所确定的范围边界)外面去了,那么j点无论如何缩减范围都不可能是id回文串的子串,就不满足上面加粗的结论了。就一定只能从1开始慢慢试探。这就是当mx  < i的时候,MP[i] = 1的原因了。

还有两种情况

一种就是上图中,j所确定的回文串完全被包含,即整个串都是其子串。那么i的可确定回文串范围就是j的回文串范围,MP[i]就变成了MP[j]。

还有一种情况就是j的回文串已经超出了mx的范围

mx的对称点            j                 id                     i              mx

对于绿线以外的区域完全未知,所以必须将MP[j]减去红线外的范围才是i的可确定范围。或者理解为只有两端都去掉外面的部分之后,剩下的才是id回文串的子串,才可以对称过去成为i的回文串。然后再在已确定的范围基础上向两边扩展。

最长回文 HDU - 3068(马拉车算法)的更多相关文章

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

    http://acm.hdu.edu.cn/showproblem.php?pid=3068 最长回文 Time Limit: 4000/2000 MS (Java/Others)    Memory ...

  2. 最长回文子串 —— Manacher (马拉车) 算法

    最长回文子串 回文串就是原串和反转字符串相同的字符串.比如 aba,acca.前一个是奇数长度的回文串,后一个是偶数长度的回文串. 最长回文子串就是一个字符串的所有子串中,是回文串且长度最长的子串. ...

  3. 最长回文 HDU - 3068 manacher 模板题

    题意:找串的最长回文字串(连续) 题解:manacher版题 一些理解:首位加上任意两个字符是为了判断边界. 本算法主要是为了 1.省去奇偶分类讨论. 2.防止形如aaaaaaa的串使得暴力算法蜕化为 ...

  4. 最长回文 HDU 3068 (裸的Manacher)

    直接看代码: ============================================================================================= ...

  5. Leetcode 5. Longest Palindromic Substring(最长回文子串, Manacher算法)

    Leetcode 5. Longest Palindromic Substring(最长回文子串, Manacher算法) Given a string s, find the longest pal ...

  6. 最长回文子串的Manacher算法

    对于一个比较长的字符串,O(n^2)的时间复杂度是难以接受的.Can we do better? 先来看看解法2存在的缺陷. 1) 由于回文串长度的奇偶性造成了不同性质的对称轴位置,解法2要对两种情况 ...

  7. 最长回文子串(Manacher算法)

    回文字符串,想必大家不会不熟悉吧? 回文串会求的吧?暴力一遍O(n^2)很简单,但当字符长度很长时便会TLE,简单,hash+二分搞定,其复杂度约为O(nlogn), 而Manacher算法能够在线性 ...

  8. 51nod1089(最长回文子串之manacher算法)

    题目链接: https://www.51nod.com/onlineJudge/questionCode.html#!problemId=1089 题意:中文题诶~ 思路: 我前面做的那道回文子串的题 ...

  9. 求最长回文子串:Manacher算法

    主要学习自:http://articles.leetcode.com/2011/11/longest-palindromic-substring-part-ii.html 问题描述:回文字符串就是左右 ...

随机推荐

  1. Undertow

    Spring Boot 内嵌容器Undertow参数设置 配置项: # 设置IO线程数, 它主要执行非阻塞的任务,它们会负责多个连接, 默认设置每个CPU核心一个线程 # 不要设置过大,如果过大,启动 ...

  2. 浏览器环境下的microtaks和macrotasks

    带有可视代码执行顺序的原文链接https://jakearchibald.com/201...,此篇文字并非其完整翻译,加入了一部分自己的理解,比如将其中的task替换为macrotask或是删除了可 ...

  3. 连接Android模拟器

    一.如何找到adb?    安装夜神安卓模拟器后,电脑桌面会有“夜神模拟器”的启动图标,鼠标右键--打开文件所在的位置,就会进入***\Nox\bin,默认路径是C:\Program Files (x ...

  4. Flutter移动电商实战 --(26)列表页_使用Provide控制子类-2

    主要实现功能,点击一级分类,二级分类跟着变.这里主要用我们的provide 新建provide provide文件夹下创建:child_category.dart 事件上就是这个实体:BxMallSu ...

  5. 如何配置WAMP环境(主要是Apache与PHP)

    1.配置Apache 1.编辑Apache配置文件---http.conf(位于安装目录下的conf子目录内): 2.修改Document Root 和 Directory选项,这是修改Apache的 ...

  6. C++重写(覆盖)、重载、重定义、多态

    1 重写(覆盖)override override是重写(覆盖)了一个方法,以实现不同的功能.一般用于子类在继承父类时,重写(覆盖)父类中的方法.函数特征相同,但是具体实现不同. 重写需要注意: 被重 ...

  7. ThinkPHP6.0学习之安装及问题解决

    ThinkPHP6.0学习之安装及问题解决 ThinkPHP6.0开发版已经上线了,我已经等了他很久了,现在写一个系列来记录Thinkphp6.0的使用,我们现在从安装开始学习吧. 首先我们要确定Th ...

  8. Swift 可选链

    可选链(Optional Chaining)是一种可以请求和调用属性.方法和子脚本的过程,用于请求或调用的目标可能为nil. 可选链返回两个值: 如果目标有值,调用就会成功,返回该值 如果目标为nil ...

  9. kotlin 修饰符

    在kotlin中有四种修饰符: private 仅在类的内部使用 protected类似private,但在子类中可以访问 internal任何在模块内部类都可以访问 public:任何类都可以访问

  10. 前端中关于HTML标签的属性for的理解

    First:<label>的说明:1.<label>标签为input元素定义标注(标识)2.label元素不会像用户呈现任何特殊的效果,仅作为显示扩展:不过,它为鼠标用户改进了 ...