今天打算补前晚 BC 的第二题,发现要用到能在 O(n) 时间求最大回文子串长度的 Manacher 算法,第一次听,于是便去百度了下,看了大半天,总算能看懂了其思想,至于他给出的代码模板我没能完全看懂,只好自己试着实现,发现理解了思想后还是能实现出来的,用自己的风格去写更好理解,先附上讲解 Manacher 算法的几个链接:

  Manacher算法--O(n)回文子串算法 (我就是看这个理解的~)

  Manacher算法处理字符串回文

  hdu3068之manacher算法+详解

  浅谈manacher算法

  hdu 3068 正好是裸题,我便试着写下,我是这样子构造新串的:

  hdu 3068 代码如下:

 #include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N = ; // str 为原串, s 为新串
char str[N], s[N << ];
int p[N << ];
// p[i] 表示以 s[i] 为中心时的回文半径,不包括 p[i]
// 即若 s[i - 1] != s[i + 1] 时,p[i] = 0; int main() {
while(~scanf("%s",str)) {
int n = strlen(str);
s[] = '$'; // 构造新串
s[] = '#';
for(int i = ; i < n; ++i) {
s[i * + ] = str[i]; // 下标要处理好
s[i * + ] = '#';
}
n = n * + ; // 更新新串的长度
s[n] = '\0'; // 最后的结束符别忘了 // right 记录的是在 i 之前的回文串中,某个回文串延伸至最右端的位置
// id 就是该回文串的下标(注意都是在新串中的)
int right = , id = ;
p[] = ;
// 因为是 s[0] == '$',作为特殊标记,左右两边都没有相等的,所以初始化为 0,
// 同理 right 一开始能延伸到的位置就是 s[0] 的位置,也就是 0,id 当然也为 0 // 主算法要开始了
for(int i = ; i < n; ++i) {
if(right > i)
p[i] = min(p[ * id - i], right - i);
else p[i] = ;
while(s[i + p[i] + ] == s[i - p[i] - ]) ++p[i];
if(i + p[i] > right) {
right = i + p[i];
id = i;
}
} // printf("\n下标: ");
// for(int i = 0; i <= n; ++i)
// printf("%d ",i);
// puts("");
// printf("新串: ");
// for(int i = 0; i < n; ++i)
// printf("%c ",s[i]);
// printf(" \\0\np[i]: ");
// for(int i = 0; i < n; ++i)
// printf("%d ",p[i]);
// puts(""); int ans = ;
for(int i = ; i < n; ++i)
ans = max(ans, p[i]); // p[i] 就是原串中的回文长度, 无须作任何 +1、-1
printf("%d\n",ans);
}
return ;
}

  还有一题也是需要用到这个算法的,hdu 3294,只是对于最后的结果输出需要处理一下,恶心的模拟,直接贴代码了:

 #include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N = ; char str[N], s[N << ];
int p[N << ]; int main() {
while(gets(str)) {
int n = strlen(str);
s[] = '$';
s[] = '#';
for(int i = ; i < n; ++i) {
s[i * - ] = str[i];
s[i * - ] = '#';
}
n = n * - ;
s[n] = '\0'; int right = , id = ;
p[] = ;
for(int i = ; i < n; ++i) {
if(right > i)
p[i] = min(p[id * - i], right - i);
else p[i] = ;
while(s[i + p[i] + ] == s[i - p[i] - ]) ++p[i];
if(i + p[i] > right) {
right = i + p[i];
id = i;
}
}
int Max = , mid;
for(int i = ; i < n; ++i) {
if(p[i] > Max) {
Max = p[i];
mid = i;
}
}
if(Max == ) {
puts("No solution!");
continue;
} int strid = (mid - Max + ) / + ;
printf("%d %d\n", strid - , strid - + Max - ); for(int i = ; i < Max; ++i) {
char ch = str[strid + i] + ('a'- str[]);
if(ch < 'a') ch = 'z' + - ('a' - ch);
else if(ch > 'z') ch = 'a' - + (ch - 'z');
printf("%c",ch);
}
puts("");
}
return ;
}

Manacher 算法(hdu 3068 && hdu 3294)的更多相关文章

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

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

  2. HDU 3068:最长回文(Manacher算法)

    http://acm.hdu.edu.cn/showproblem.php?pid=3068 最长回文 Problem Description   给出一个只由小写英文字符a,b,c...y,z组成的 ...

  3. hdu 3068 最长回文 (Manacher算法求最长回文串)

    参考博客:Manacher算法--O(n)回文子串算法 - xuanflyer - 博客频道 - CSDN.NET 从队友那里听来的一个算法,O(N)求得每个中心延伸的回文长度.这个算法好像比较偏门, ...

  4. HDU 3068 最长回文 Manacher算法

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

  5. Hdu 3068 最长回文字串Manacher算法

    题目链接 最长回文 Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total S ...

  6. HDU - 3068 最长回文(manacher算法)

    题意:给出一个只由小写英文字符a,b,c...y,z组成的字符串S,求S中最长回文串的长度. 分析: manacher算法: 1.将字符串中每个字符的两边都插入一个特殊字符.(此操作的目的是,将字符串 ...

  7. hdu 3068 最长回文 manacher

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

  8. HDU - 3068 最长回文 【Manacher】

    题目链接 http://acm.hdu.edu.cn/showproblem.php?pid=3068 思路 n^3 的做法 对于每个字符 同时 往左往右搜 但是要分奇偶 就是 n^3 n^2 的做法 ...

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

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

随机推荐

  1. js命名空间笔记

    在量比较大或者多人编写的情况下,命名冲突就很有可能发生,同一个页面引用了两个命名相同功能不同的文件,调用的时候就会出问题.因此使用JS命名空间很重要. 1.采用字面量方法创建命名空间: var a={ ...

  2. java ClassLoader与动态扩展

    摘自:http://blog.csdn.net/moreevan/article/details/6654781

  3. netsh winsock reset 11003

    netsh winsock reset 11003 http://files.cnblogs.com/xsmhero/winsock.zip

  4. 模块mod_h323的编译

    去h.323plus官网上下载关联的库 http://www.h323plus.org/source/ 很贴心,分操作系统下载,而且关联的ptlib库的版本也一并列了出来. 一.编译ptlib库 ex ...

  5. DbUtils使用时抛出Cannot get a connection

    java.sql.SQLException: Cannot get a connection, pool error Timeout waiting for idle object Caused by ...

  6. Map Columns From Different Tables and Create Insert and Update Statements in Oracle Forms

    This is one of my most needed tool to create Insert and Update statements using select or alias from ...

  7. deep-learning-frameworks

    From: http://venturebeat.com/2015/11/14/deep-learning-frameworks/ Here’s a rundown of some other not ...

  8. [HDU5727]Necklace(二分图最大匹配,枚举)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5727 题意:有N个阴珠子和N个阳珠子,特定序号的阴阳珠子放在一起会让阳珠子暗淡.现在问排放成一个环,如 ...

  9. 【转】The decoupling capacitor…is it really necessary?

    Before working as an applications engineer, I worked as an IC test development engineer here at TI. ...

  10. 用@RequestMapping映射请求

    DispatcherServlet接受一个web请求之后,将请求发送给@Controller注解声明的不同控制器类. 这个调度过程依赖控制器类及其处理程序方法中声明的各种@RequestMapping ...