今天打算补前晚 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. Android调试常用的工具简单介绍

    配置Android环境的时候,我们需要安装sdk.在sdk的目录下: platform-tools 目录下的adb tool下的: ddms.bat adb :可以cd 当前目录,然后使用相应的命令, ...

  2. recv send 阻塞和非阻塞

    http://blog.csdn.net/xiaofei0859/article/details/6037814 int send( SOCKET s, const char FAR *buf, in ...

  3. gulp 建立一个简单的自动化

    前端项目需要的功能: 1.图片(压缩图片支持jpg.png.gif) 2.样式 (支持sass 同时支持合并.压缩.重命名) 3.javascript (检查.合并.压缩.重命名) 4.html (压 ...

  4. python学习笔记三 文件操作(基础篇)

    文件操作 打开文件 open(name[,mode[,buffering]])   open函数使用一个文件名作为强制参数,然后返回一个文件对象.[python 3.5 把file()删除掉]   w ...

  5. 集合、ArrayList 集合。Stack集合。Queue集合。以及Hashtable集合

    arrayList 首先复制Colections加  : 创建arrayList ar =new arrayList(); //ArrayList al=new ArrayList();        ...

  6. #define用法集锦

    Definition: The #define Directive You can use the #define directive to give a meaningful name to a c ...

  7. HTML5/CSS3(PrefixFree.js) 3D文字特效

    之前在园子里看到一个HTML5/CSS3的文字特效(这里),觉得挺好玩的所以小小的研究了下,不过发现代码都是针对webkit以及FF的所以IE跪了. Runjs 我将示例中的代码进行了精简,后来发现C ...

  8. C#读写本地ini

    //读写INI public class GF_INI { [DllImport("kernel32")] private static extern long WritePriv ...

  9. BZOJ 2568 比特集合

    题目链接:http://www.lydsy.com:808/JudgeOnline/problem.php?id=2568 题意:维护一个集合S,支持以下操作: (1)INS M : 将元素 M 插入 ...

  10. The property 'RowId' is part of the object's key information and cannot be modified.

    2016-10-20 10:19:46,667 [12] ERROR ClientApp.FormDownload - ErrorSystem.InvalidOperationException: T ...