HDU - 3068 最长回文(manacher)
HDU - 3068
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 Source |
题目要求求出最长回文子串,是一道manacher的模板题。
我们先讲一下manacher,我们先处理一下字符串,把字符串处理成#a#a#这样的格式,比如abcd处理成#a#b#c#d#,这样的好处是解决了判断回文串是奇数和偶数的问题,把回文串强制变成奇数。接下来,定义一个p[]数组,p[i]代表以节点i为中心的最长回文串的半径。例如aaaa这个字符串,p[0]=p[3]=1,p[1]=p[2]=2。同时我们定义一个变量mx和id,mx代表当前判断过的回文子串最长延伸(往右)到哪里,可以理解为当前判断过的回文子串到达的最大下标。而id代表当前更新的mx值所对应的回文串的中心的下标。如果不是很清楚可以直接看下代码。剩下部分直接看代码注释吧。最好自己在纸上画一下
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <vector>
#include <queue>
#include <stack>
#include <map>
#include <set>
#define X first
#define Y second
#define clr(u,v); memset(u,v,sizeof(u));
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
const int maxn=2e5+;//注意开两倍大小
const int INF=0x3f3f3f3f;
char s[maxn],str[maxn];//s为原字符串,str为处理后的字符串
int p[maxn];//p[i]代表以i为中心的回文串的最长半径
int len1,len2;//分别代表s的长度和str的长度
void init()//预处理出str
{
len1=strlen(s);
str[]='$';//在首位加一个特殊字符,防止越界
str[]='#';
for (int i=;i<len1;i++)
{
str[*i+]=s[i];
str[*i+]='#';
}
len2=len1*+;
str[len2]='\0';//不能和首位字符一样
}
void manacher()
{
int mx=,id=;
for (int i=;i<len2;i++)
{
if (mx>i) //如果当前的i在mx以内,说明i为我们之前求的回文串的范围里面
p[i]=min(p[*id-i],mx-i);//2*id-i代表i关于id对称的下标,我们前面求出他是回文串,因此具备了对称性,而2*id-i一定小于i,我们的i是从左到右扫描的,所以p[2*id-i]一定处理出来了,所以我们可以直接用p[2*id-i]的值,但是他不能超过mx-i,因为超过mx值我们就不能保证它是回文串,所以取二者最小
else p[i]=;//如果i不在回文串的范围内,则初始化p[i]=1;
for (;str[i-p[i]]==str[i+p[i]];p[i]++);//暴力往两边匹配,找到以i为中心的最长回文串
if (mx<i+p[i])更新mx值和id值
{
mx=i+p[i];
id=i;
}
}
}
int solve()
{
int ans=;
for (int i=;i<len2;i++)
if (ans<p[i]) ans=p[i];//找最大的p[i]就是答案
return ans-;
}
int main()
{
while (~scanf("%s",s))
{
init();
manacher();
printf("%d\n",solve());
}
return ;
}
HDU - 3068 最长回文(manacher)的更多相关文章
- hdu 3068 最长回文 manacher算法(视频)
感悟: 首先我要Orz一下qsc,我在网上很难找到关于acm的教学视频,但偶然发现了这个,感觉做的很好,链接:戳戳戳 感觉这种花费自己时间去教别人的人真的很伟大. manacher算法把所有的回文都变 ...
- hdu 3068 最长回文 manacher
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3068 给出一个只由小写英文字符a,b,c...y,z组成的字符串S,求S中最长回文串的长度.回文就是正 ...
- hdu 3068 最长回文(manacher&最长回文子串)
最长回文 Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Submi ...
- hdu 3068 最长回文(manacher入门)
最长回文 Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submis ...
- HDU - 3068 最长回文manacher马拉车算法
# a # b # b # a # 当我们遇到回判断最长回文字符串问题的时候,若果用暴力的方法来做,就是在字符串中间添加 #,然后遍历每一个字符,找到最长的回文字符串.那么马拉车算法就是在这个基础上进 ...
- HDU 3068 最长回文 manacher 算法,基本上是O(n)复杂度
下面有别人的比较详细的解题报告: http://wenku.baidu.com/view/3031d2d3360cba1aa811da42.html 下面贴我的代码,注释在代码中: #include ...
- HDU 3068 最长回文 Manacher算法
Manacher算法是个解决Palindrome问题的O(n)算法,能够说是个超级算法了,秒杀其它一切Palindrome解决方式,包含复杂的后缀数组. 网上非常多解释,最好的解析文章当然是Leetc ...
- hdu 3068 最长回文(manachar求最长回文子串)
题目连接:hdu 3068 最长回文 解题思路:通过manachar算法求最长回文子串,如果用遍历的话绝对超时. #include <stdio.h> #include <strin ...
- hdu 3068 最长回文 (Manacher算法求最长回文串)
参考博客:Manacher算法--O(n)回文子串算法 - xuanflyer - 博客频道 - CSDN.NET 从队友那里听来的一个算法,O(N)求得每个中心延伸的回文长度.这个算法好像比较偏门, ...
随机推荐
- 基于gulp编写的一个简单实用的前端开发环境好了,安装完Gulp后,接下来是你大展身手的时候了,在你自己的电脑上面随便哪个地方建一个目录,打开命令行,然后进入创建好的目录里面,开始撸代码,关于生成的json文件请点击这里https://docs.npmjs.com/files/package.json,打开的速度看你的网速了注意:以下是为了演示 ,我建的一个目录结构,你自己可以根据项目需求自己建目
自从Node.js出现以来,基于其的前端开发的工具框架也越来越多了,从Grunt到Gulp再到现在很火的WebPack,所有的这些新的东西的出现都极大的解放了我们在前端领域的开发,作为一个在前端领域里 ...
- 【Zookeeper】源码分析之持久化--FileSnap
一.前言 前篇博文已经分析了FileTxnLog的源码,现在接着分析持久化中的FileSnap,其主要提供了快照相应的接口. 二.SnapShot源码分析 SnapShot是FileTxnLog的父类 ...
- iOS开发-OC语言 (五)字典
字典 主要知识点: 1.NSDictionary 类 2.NSMutableDictionary 类 3.了解NSMutableDictionary 与 NSDictionary 的继承关系 4.补充 ...
- 使用pip安装报错的处理方法
在新的机子上使用pip安装程序一直报错: Retrying (Retry(total=4, connect=None, read=None, redirect=None)) after connect ...
- 【LeetCode】29. Divide Two Integers
题意:不用乘除求余运算,计算除法,溢出返回INT_MAX. 首先考虑边界条件,什么条件下会产生溢出?只有一种情况,即返回值为INT_MAX+1的时候. 不用乘除求余怎么做? 一.利用减法. 耗时太长, ...
- hdu 5997 rausen loves cakes(线段数合并+启发式修改)
题目链接:hdu 5997 rausen loves cakes 题意: 给你n个点,每个点有一个颜色,现在有两个操作,第一个操作,将颜色x改为颜色y,第二个操作,询问[x,y]区间有多少颜色段(颜色 ...
- 循序渐进看Java web日志跟踪(3)-Log4J的使用和配置
之前说过关于java日志跟踪的几大主要用的框架,也说到了,其实在其中,Log4J充当着一个相当重要的角色.目前,大部分框架也都是采用的是Log4J,虽然说它已经停止了更新,作者也重新起了LogBack ...
- iOS APP中Versions和build版本区别
version是app发布时用户看到的版本号. build的为了方便开发者多次提交binary, 比如被苹果reject后. 例如,第一次提交version和build都是1.0. 假如审核没过,那么 ...
- 3.使用secureCRT连接PC,LINUX,开发板
1.设置secureCRT(可选项):http://www.linuxyw.com/linux/gongxiang/20130505/161.html 2.使用secureCRT远程登录linux 3 ...
- 爬虫代码实现五:解析所有分页url并优化解析实现类
如图,我们进入优酷首页,可以看到电视剧列表,我们称这个页面为电视剧列表页,而点击进入某个电视剧,则称为电视剧详情页.那么如何获取所有分页以及对应的详情页呢,通过下面的分页得到. 因此,首先,我们将St ...