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. Mac下Maven的删除和安装

    一 删除maven 找到当前的maven路劲:使用mvn -v查看当前maven的安装目录在哪 删掉sudo rm -rf [maven的路径] 二 安装maven 1.下载maven压缩包 mac下 ...

  2. jumpserver官方手动安装

    测试环境 CPU: 64位双核处理器 内存: 4G DDR3 数据库:mysql 版本大于等于 5.6 mariadb 版本大于等于 5.5.6 环境 系统: CentOS 7 IP: 192.168 ...

  3. 我终于搞清楚了和String有关的那点事儿。

    String,是Java中除了基本数据类型以外,最为重要的一个类型了.很多人会认为他比较简单.但是和String有关的面试题有很多,下面我随便找两道面试题,看看你能不能都答对: Q1:String s ...

  4. c 判断字符是否为字母 (iswalpha example)

    #include <stdio.h> #include <wctype.h> int main () { ; wchar_t str[] = L"C++"; ...

  5. ScvQ常用的网站(持续更新...)

    GitHub:https://github.com/ScvQ 幕课网:https://www.imooc.com/u/4659537/courses 免费的SS:https://global.isha ...

  6. Restorator软件使exe文件都不能打开,exe不支持此接口

    遇到的问题: 下载了一个软件Restorator(资源修改器),填写完注册码之后,所有的exe文件都不能打开了,任务管理器不支持此接口打不开. 问题原因: 软件Restorator关联exe文件,运行 ...

  7. 如何捕捉Desried Capabilities中的appPackafe和appActive

    捕捉这两个参数需要借助adb工具的日志进行分析.ADB是一种命令行工具,用于PC和Android模拟器之前连接通信,集成在Android ADK中,默认在platfrom-tools目录下.在cmd运 ...

  8. SQL-W3School-基础:SQL DISTINCT 语句

    ylbtech-SQL-W3School-基础:SQL DISTINCT 语句 1.返回顶部 1. 本章讲解 SELECT DISTINCT 语句. SQL SELECT DISTINCT 语句 在表 ...

  9. JAVA踩坑录

    以前踩了很多坑,大多忘了.现在踩了坑,想起了一定记下来. 1. 字符串分割,这种工具类,首次使用一定要先看一眼,不然跳坑 commons-lang StringUtils.split分割时会去掉空串: ...

  10. 阶段5 3.微服务项目【学成在线】_day04 页面静态化_05-freemarker基础-List指令

    controller填充数据 @RequestMapping("/freemarker") @Controller public class FreemarkerControlle ...