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. JVM备忘点(1.8以前)

    1.内存结构 左边两个线程共享,右边三个线程私有. 方法区:.class文件的类信息.常量.static变量.即时编译器编译后的代码(动态代理).HotSpot将方法区称为永久代 堆:分为新生代和老年 ...

  2. laotech老师唠科mac 深入浅出MAC OS X ceshi ruguokeyi

    laotech老师唠科mac 深入浅出MAC OS X http://study.163.com/plan/planLearn.htm?id=1637004#/learn/resVideo?lesso ...

  3. java试题复盘——11月25日

    上: 11.下列表述错误的是?(D) A.int是基本类型,直接存数值,Integer是对象,用一个引用指向这个对象. B.在子类构造方法中使用super()显示调用父类的构造方法,super()必须 ...

  4. Android 之Activity启动模式(二)之 Intent的Flag属性

    首页博客链接关于我留言板 前面介绍了通过launchMode设置Activity的启动模式.本章接着介绍Activity的启动模式相关内容,讲解的内容是Intent与启动模式相关的Flag,以及and ...

  5. 【原创】CancellableWait

    应用程序不能正常退出,导致无法关机,这种情况通常是应用程序在等待一些I/O request to finish. 应用程序访问远程文件时,这种情况的发生更加频繁. If an application ...

  6. linux安装puppeteer

    1.安装 下载淘宝镜像的,可以同时下载puppeteer和chromium下面两条语句即可 npm install -g cnpm --registry=https://registry.npm.ta ...

  7. win10系统在执行“ vagrant box add centos7 vagrant-centos-7.box”添加box时,报错“Vagrant failed to initialize at a very early stage: Failed to locate the powershell executable on the available PATH. ”

    这个意思是:在有效的路径中未能执行PowerShell命令. 请检查PowerShell的安装和有效的路径,然后再尝试重新运行这个命令. 在环境变量path中添加powershell的路径,例如:C: ...

  8. MySQL索引选择及添加原则

    索引选择性就是结果个数与总个数的比值. 用sql语句表示为: SELECT COUNT(*) FROM table_name WHERE column_name/SELECT COUNT(*) FRO ...

  9. leetcode 96. Unique Binary Search Trees 、95. Unique Binary Search Trees II 、241. Different Ways to Add Parentheses

    96. Unique Binary Search Trees https://www.cnblogs.com/grandyang/p/4299608.html 3由dp[1]*dp[1].dp[0]* ...

  10. Activiti核心API

    ProcessEngine 说明: 1)      在Activiti中最核心的类,其他的类都是由他而来. 2)      产生方式: 在前面看到了两种创建ProcessEngine(流程引擎)的方式 ...