HDU3068 最长回文(Manacher算法)
来源:互联网 发布:淘宝怎么清空购物车 编辑:程序博客网 时间:2024/04/28 07:13
Problem Description
给出一个只由小写英文字符a,b,c...y,z组成的字符串S,求S中最长回文串的长度.
回文就是正反读都是一样的字符串,如aba, abba等
回文就是正反读都是一样的字符串,如aba, abba等
Input
输入有多组case,不超过120组,每组输入为一行小写英文字符a,b,c...y,z组成的字符串S
两组case之间由空行隔开(该空行不用处理)
字符串长度len <= 110000
两组case之间由空行隔开(该空行不用处理)
字符串长度len <= 110000
Output
每一行一个整数x,对应一组case,表示该组case的字符串中所包含的最长回文长度.
Sample Input
aaaaabab
Sample Output
43
这道题的模板来自kuangbin大神,我加上了一点自己的图文解释。
判断回文串最麻烦的一点就是要分奇数和偶数考虑,而Manacher算法就是用一种巧妙的方法,将奇数和偶数放在一起考虑。
具体做法就是在原字符串每两个字符中插入分隔符,首尾也要加上分隔符,防止越界。用Ma[i]记录预处理后的字符串。
用一个数组Mp[i]记录以字符Ma[i]为中心的最长回文字符串的长度。
如下图所示:
如何计算Mp[i]呢?
首先我们先定义几个数。
int mx;//当前已经已经回文串最右字符的最大值
int id;//回文串最右字符的最大值的中心位置
分两种情况考虑。
第一种情况:i<mx
首先找到i关于id的对称位置j(id*2-i),然后还要分两种情况考虑。
1、如果以j为中心的最长回文串在以id为中心的最长回文串的里面,以i为中心的最长回文串就等于以j为中心的最长回文串。
Mp[i]=Mp[j];
2、如果以j为中心的最长回文串超过了以id为中心的最长回文串,那么一开始以i为中心的只能保证黄色部分一定是回文串,最右超过mx部分的只能重新开始匹配。
Mp[i]=mx-i;
我曾经有一瞬间是迷惑不解的,觉得应该是(mx-1)*2,但是我后来想起来处理后的字符串里有“#”啊,所以应该是mx-1。那么重新开始匹配的时候也是匹配了一个字符,就++,而不是+2。
另外,如果新计算的回文串右端点大于mx,就要更新mx和id哦!
第二种情况:
i>=mx
那就老老实实的一个一个重新匹配吧。
以下是完整的代码:
#include<iostream>#include<cstring>#include<algorithm>#include<cstdio>const int MAXN=110010;using namespace std;char s[MAXN];char Ma[MAXN*2];int Mp[MAXN*2];void Manacher(char s[],int len){int l=0;Ma[l++]='$';Ma[l++]='#';for(int i=0;i<len;i++){Ma[l++]=s[i];Ma[l++]='#';}Ma[l]=0;int mx=0,id=0;for(int i=0;i<l;i++){Mp[i]=mx>i?min(Mp[2*id-i],mx-i):1;while(Ma[i+Mp[i]]==Ma[i-Mp[i]])Mp[i]++;if(i+Mp[i]>mx){mx=i+Mp[i];id=i;}}}int main(void){while(scanf("%s",s)==1){int ans=0;int len=strlen(s);Manacher(s,len);for(int i=0;i<2*len+2;i++)ans=max(ans,Mp[i]-1);printf("%d\n",ans);}return 0;}
0 0
- hdu3068 最长回文(manacher 算法)
- hdu3068最长回文(manacher算法)
- HDU3068 最长回文(Manacher算法)
- HDU3068 最长回文(Manacher算法)
- HDU3068-最长回文(Manacher算法)
- 【Manacher算法】hdu3068 最长回文
- HDU3068最长回文 Manacher算法
- hdu3068 最长回文--Manacher算法
- hdu3068(最长回文manacher)
- Manacher(hdu3068最长回文)
- hdu3068 最长回文(manacher)
- HDU3068 最长回文(manacher)
- hdu3068 最长回文 poj3974 Palindrome(Manacher算法)
- manacher算法求最长回文子串(hdu3068)
- HDU3068(最长回文子串manacher算法)
- HDU3068/Leetcode5 最长回文 (Manacher算法)
- HDU3068-manacher算法-最长回文串
- 【HDU3068】最长回文【manacher】
- test
- C++标准库容器 vector
- python socket编程(1)
- Android属性动画解析(中),ValueAnimator和ObjectAnimator的高级用法
- sevlet 3.0 web项目搭建及web.xml讲解
- HDU3068 最长回文(Manacher算法)
- C语言变参函数
- Java系列笔记(4) - JVM监控与调优 和相关博客
- shell笔记(4):正则表达式
- solrconfig.xml 应用解析调优
- android绘制实心。空心五角星
- iOS 页面之间的传值总结
- hihoCoder 1261 String Problem II
- HDU 1619:Unidirectional TSP【dfs & 回忆路径】