http://acm.hdu.edu.cn/showproblem.php?pid=3068

最长回文

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
 
下面简单说下看了Manacher算法的想法,我是通过 https://www.felix021.com/blog/read.php?2040 学到的,具体的学习可以参考该博客。
 
当时一看这个算法觉得十分厉害啊,先把我们要求的字符串先预处理一下,把无论奇偶长度的字符串都变成奇数长度的,就是例如样例,我们把“aaaa”变成“#a#a#a#a#”,这样来处理成一个新的字符串S,然后再用一个数组P来表示当在S【i】的时候,以S【i】为中心的最长回文子串向左右扩张的最大长度,例如上面的例子,当i = 5的时候,P【5】= 5,当i = 2的时候P【i】= 2,所以明显地可以看到,我们以S【i】为中心对折对应的回文子串,对折之后的长度就是P【i】(算长度的时候在S【i】自己也是要算一位的)。那么我们可以发现,P【i】- 1表示的就是原字符串的回文子串长度。
 
接下来就是比较重点的地方就是算P【i】。在这里引入两个变量 id,xr,xl。id表示目前能够得到的最长的回文子串的中心,xr是该回文子串的右边界。即 xr = id + P【id】,同理xl是该回文子串的左边界,即xl = id - P【id】。
 
当 i < xr 的时候,我们设一个变量 j = id * 2 - i = id + (id - i),即 j 是 i 以 id 为对称点翻折过去的位置, 因为我们跑到 i 这个位置的时候,前面的 P【j】肯定被更新过了,那么可以根据P【j】和 xr - i 的关系来判断P【i】的长度。
如果P【j】 > xr - i的话,那么意味着以 j 为中心的回文子串不完全包含在以 id 为中心的回文子串里面,那么我们并不能就这样完全判断出P【i】的长度了,我们只能够了解到,因为 i < xr ,所以 j > xl,所以以 j 为中心的回文子串是有一部分包含在以 id 为中心的回文子串里边的,那么只能保证 P【i】的长度是至少有 xr - i 那么长的。至于剩下还有多长,只能用一个循环再去匹配更新P【i】了。
 如果P【j】 < xr - i的话,那么相当于以 j 为中心的回文子串完全包含在了以 id 为中心的回文子串里边,又因为 i 和 j 是关于 id 对称的并且回文串的一边和另一边是相同的,所以P【i】的长度可以直接求得等于P【j】了。
所以在 i < xr 的情况下,我们可以总结得到 P【i】= min(P【j】,xr - i )。其中 j = id * 2 - i。
 
上面都是 xr > i 的情况,那么 xr < i 的情况我们未知,只能设P【i】只包含自己本身即等于1,然后慢慢去匹配了。
 
 #include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
#define N 110010
char str[N];
char s[*N];
int p[*N];
int l;
//求最长回文子串的Manacher算法
void init()
{
memset(p, , sizeof(p));
int len = strlen(str);
s[] = '%';
l = ;
for(int i = ; i < len; i++) {
s[l++] = '#';
s[l++] = str[i];
}
s[l++] = '#';
s[l] = '\0';
} int manacher()
{
init();
int xr = , id = ;
for(int i = ; s[i]; i++) {
p[i] = xr > i ? min(p[id*-i], xr - i) : ;
while(s[i+p[i]] == s[i-p[i]]) p[i]++;
if(i + p[i] > xr) {
xr = i + p[i];
id = i;
}
}
int ans = ;
for(int i = ; i < l; i++) {
if(p[i] - > ans) ans = p[i] - ;
}
return ans; } int main()
{
while(~scanf("%s", str))
printf("%d\n", manacher());
return ;
}

HDU 3068:最长回文(Manacher算法)的更多相关文章

  1. hdu 3068 最长回文 manacher算法(视频)

    感悟: 首先我要Orz一下qsc,我在网上很难找到关于acm的教学视频,但偶然发现了这个,感觉做的很好,链接:戳戳戳 感觉这种花费自己时间去教别人的人真的很伟大. manacher算法把所有的回文都变 ...

  2. HDU 3068 最长回文 manacher 算法,基本上是O(n)复杂度

    下面有别人的比较详细的解题报告: http://wenku.baidu.com/view/3031d2d3360cba1aa811da42.html 下面贴我的代码,注释在代码中: #include ...

  3. HDU 3068 最长回文 Manacher算法

    Manacher算法是个解决Palindrome问题的O(n)算法,能够说是个超级算法了,秒杀其它一切Palindrome解决方式,包含复杂的后缀数组. 网上非常多解释,最好的解析文章当然是Leetc ...

  4. HDU - 3068 最长回文manacher马拉车算法

    # a # b # b # a # 当我们遇到回判断最长回文字符串问题的时候,若果用暴力的方法来做,就是在字符串中间添加 #,然后遍历每一个字符,找到最长的回文字符串.那么马拉车算法就是在这个基础上进 ...

  5. hdu 3068 最长回文 manacher

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3068 给出一个只由小写英文字符a,b,c...y,z组成的字符串S,求S中最长回文串的长度.回文就是正 ...

  6. hdu 3068 最长回文(manacher&amp;最长回文子串)

    最长回文 Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submi ...

  7. hdu 3068 最长回文(manacher入门)

    最长回文 Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submis ...

  8. HDU - 3068 最长回文(manacher)

    HDU - 3068 最长回文 Time Limit: 2000MS   Memory Limit: 32768KB   64bit IO Format: %I64d & %I64u Subm ...

  9. hdu 3068 最长回文(manachar求最长回文子串)

    题目连接:hdu 3068 最长回文 解题思路:通过manachar算法求最长回文子串,如果用遍历的话绝对超时. #include <stdio.h> #include <strin ...

  10. hdu_3068 最长回文(Manacher算法)

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

随机推荐

  1. SQL之Grant(分配权限)和Revoke(回收权限)

    Grant Grant可以把指定的权限分配给特定的用户,如果这个用户不存在,则会创建一个用户 命令格式 grant 权限 on 数据库名.表名 to 用户名@登陆方式 identified by 'p ...

  2. SQLServer 以备份初始化订阅

    原文:SQLServer 以备份初始化订阅 在创建事务复制时,如果发布数据库很大,使用快照初始化时,将等待很久,如果出现问题可能又得重新初始化.使用备份初始化会省很多时间,但是数据库在创建发布订阅期间 ...

  3. 记一次ASP.NET MVC4 升级到MVC5的小问题解决

    原文:记一次ASP.NET MVC4 升级到MVC5的小问题解决 .NET 4.0 MVC4版本,升级到.NET 4.6.1 MVC5: 1.使用nuget更新所有 与mvc相关的类库; 2.更改~/ ...

  4. C#图片灰度处理(位深度24→位深度8),用灰度数组byte[]新建一个8位灰度图像Bitmap 。

    原文:C#图片灰度处理(位深度24→位深度8) #region 灰度处理 /// <summary> /// 将源图像灰度化,并转化为8位灰度图像. /// </summary> ...

  5. =WM_VSCROLL(消息反射) 和 WM_VSCROLL(消息响应)的区别(控件拥有者自己不处这个理消息,而是反射给控件对象本身来处理这个消息)

    =WM_VSCROLL(消息反射) 和 WM_VSCROLL(消息响应)的区别 所谓消息反射就是控件拥有者自己不处这个理消息,而是反射给控件对象本身来处理这个消息 1.“=WM_VSCROLL”是消息 ...

  6. Perl Scripts / 脚本

    树状递归列出目录下面子目录和文件 #!/usr/bin/perl #List all files and sub-directories as tree #Under current director ...

  7. Qt中连接到同一signal的多个slots的执行顺序问题(现在是看连接顺序,以前是无序的)

    in the order they have been connected 起源 前些天忘记在哪儿讨论过这个问题,今天在csdn又看到有网友问这个问题,而其他网友却无一例外的给出了“无序”这个答案. ...

  8. 纯CSS3创意loading文字特效

    快速使用Romanysoft LAB的技术实现 HTML 开发Mac OS App,并销售到苹果应用商店中.   <HTML开发Mac OS App 视频教程> 土豆网同步更新:http: ...

  9. Qt学习虚拟机--基于MSYS2-MinGW环境并带有各种开源的软件库!

    Qt学习虚拟机--基于MSYS2-MinGW环境并带有各种开源的软件库!虚拟机地址,VM10和以上:http://pan.baidu.com/s/1slcTA49包含两个分卷压缩包,加起来5GB多. ...

  10. 可视化流程设计——流程设计器演示(基于Silverlight)

    上一篇文章<通用流程设计>对鄙人写的通用流程做了一定的介绍,并奉上了相关源码.但一个好的流程设计必少不了流程设计器的支持,本文将针对<通用流程设计>中的流程的设计器做一个简单的 ...