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. WPF ListBoxItem模板中添加CheckBox选中问题

    原文:WPF ListBoxItem模板中添加CheckBox选中问题 是这样的,需要一个ListBox来展示照片,并添加一个选中的CheckBox.这就需要对ListBox的ItemTemplate ...

  2. ng-zorro 子菜单

    效果 代码 // 初始化菜单 // res.menu是一个Menu数组 // 在后端创建子菜单 res.menu.push({ text: "", i18n: "子菜单& ...

  3. Wireshark基本介绍和学习TCP三次握手 专题

    wireshark有两种过滤器: 捕捉过滤器(CaptureFilters):用于决定将什么样的信息记录在捕捉结果中.显示过滤器(DisplayFilters):用于在捕捉结果中进行详细查找. 捕捉过 ...

  4. thinkphp5 的一些笔记

    Model里面的一些属性添加 protected $resultSetType = 'collection'; protected $autoWriteTimestamp = 'timestamp'; ...

  5. 简洁的导出 datatable到excel,不用组件

    简洁的导出 datatable到excel var lines = new List<string>(); string[] columnNames = dataTable.Columns ...

  6. UWP中String类型如何转换为Windows.UI.Color

    原文:UWP中String类型如何转换为Windows.UI.Color 我在学习过程中遇到的,我保存主题色为string,但在我想让StatusBar随着主题色变化时发现没法使用. ThemeCol ...

  7. css3 pointer-events 让对象如透明般直接响应下层对象的鼠标事件

    引用:http://www.css88.com/book/css/properties/user-interface/pointer-events.htm 语法: pointer-events:aut ...

  8. 【Windows10 IoT开发系列】PowerShell的相关配置

    原文:[Windows10 IoT开发系列]PowerShell的相关配置 可使用 Windows PowerShell 远程配置和管理任何 Windows 10 IoT 核心版设备.PowerShe ...

  9. 在Windows IoT上使用网络摄像头

    在树莓派上可以使用它官方标配的摄像头,但是这个摄像头似乎不能被Windows IoT识别和使用.但是,可以在树莓派的USB口上插入任意型号的摄像头,就可以实现树莓派的拍摄功能. 关于摄像头的寻找和拍摄 ...

  10. 轻量级 Material Design 前端框架 MDUI (纯html,css,与css框架跟react vue不冲突)

    MDUI 是一个轻量级的 Material Design 前端框架,对照着 Material Design 文档进行开发,争取 1:1 实现 Material Design 中的组件. 多主题支持 M ...