最长回文
来源:互联网 发布:网络综艺为什么这么火 编辑:程序博客网 时间:2024/06/08 17:52
**bzoj 2565: 最长双回文串 manacher算法
2565: 最长双回文串
Time Limit: 20 Sec Memory Limit: 256 MB**
题目连接
http://www.lydsy.com/JudgeOnline/problem.php?id=2565
Description
顺序和逆序读起来完全一样的串叫做回文串。比如acbca是回文串,而abc不是(abc的顺序为“abc”,逆序为“cba”,不相同)。
输入长度为n的串S,求S的最长双回文子串T,即可将T分为两部分X,Y,(|X|,|Y|≥1)且X和Y都是回文串。
Input
一行由小写英文字母组成的字符串S。
Output
一行一个整数,表示最长双回文子串的长度。
Sample Input
baacaabbacabb
Sample Output
12
先简单的说一下 题目的意思,给你一个 字符串,让你求出 最长的 双回文字串,双回文字串就是, 该字符串可以 有 两个 回文字符串 组成, 这两个 回文字符串的长度 不小于 1 。题目的意思很简单,下面说一下我写的程序的 解体思路,我 先是 运用 manacher 函数的出 p[] 数组,p[i] 表示 以 str[i] 为中心的 的 最大的回文字符串的长度,然后 ,定义了, 一个 L【】 数组, L[i] 表示 包含 str[i] 这个字符的 中心点 最 靠左边 的 回文子字符串的 中心 字符 的 下标, 然后 有定义了一个 R[] 数组, 与 上面的 L[] 数组功能类似, L[i] 存储 包含 str[i] 这个字符的 中心点 最 靠右边 的 子 回文字符串 的 中心 字符 的 下标。
然后 根据 循环 运用 p【】数组 对 R L 两个 数组分别进行赋值。
赋值 之后, 通过 一个 循环 遍历, 得出 最唱 双 回文字符串的 长度。
循环 遍历的 核心 代码 为:
for(int i = 1; i < len; i++) ans = max(ans, R[2*i+1] - L[2*i+1]);
代码的意思 就是 对于 一个 字符 str[2*i+1] 包含该字符 的 最右边的 回文串的 中心 字符的 下标 减去 包含 个字符的 最左边 的 回文串 的 中心 字符 的 下标;大家 把这个 解释 与 题目种 所说的 双 回文字符串的 定义 结合 在一起 想一想 就会明白的;
#include <iostream>#include <cstdio>#include <cstring>#include <string>#include <algorithm>#define MAX 100010using namespace std;char str[MAX*2];int p[MAX*2];int R[MAX*2];int L[MAX*2];void Manacher(){ int len = strlen(str); for(int i = len; i >= 0; i--) { str[2*i+2] = str[i]; str[2*i+1] = '#'; } str[0] = '?'; int id = 0; int maxlen = 0; for(int i = 2; i <= 2*len; i++) { if(id+p[id] > i) p[i] = min(p[id-(i-id)], p[id]-(i-id)); else p[i] = 1; while(str[i+p[i]] == str[i-p[i]]) p[i]++; if(i+p[i] > id+p[id]) id = i; maxlen = max(maxlen, p[i]); } // 求 R[] 与 L[] 数组 int pos = 1; for(int i = 2; i <= 2*len; i++) for( ; pos <= i+p[i]-1; pos++) L[pos] = i; pos = 2*len; for(int i = 2*len; i >= 2; i--) for( ; pos >= i-p[i]+1; pos--) R[pos] = i; int ans = 0; for(int i = 1; i < len; i++)// 这里2*i+1 表示 ‘#’的下表 而且 是 包含在 用用字符 之间的 添加字符 的下标 ans = max(ans, R[2*i+1] - L[2*i+1]); printf("%d\n", ans);}int main(){ scanf("%s", str); memset(L, 0, sizeof(L)); memset(R, 0, sizeof(R)); Manacher(); return 0;}
- 最长回文
- 最长回文
- 最长回文
- 最长回文
- 最长回文
- 最长回文
- 最长回文
- 最长回文
- 最长回文
- 最长回文
- 最长回文
- 最长回文
- 最长回文子串
- 最长回文子串
- 最长回文子串
- 最长回文长度
- 最长回文子串
- 最长回文子串
- codeforces734D
- tensorflow基础
- 只用路径上传文件,不用手动选择文件上传
- Dipping into Shared Memory
- Super Jumping! Jumping! Jumping! hdu1087
- 最长回文
- 51nod 1821 最优集合 并查集 || 栈
- Unity中OnCollisionStay2D的使用
- RE:JAVA学习-集合操作
- 剑指Offer—23—二叉搜索树的后序遍历序列
- 2017.08.23总结
- 回归计划-序
- mac上的几个键⌘——Command ⌃ ——Control是向上的尖括号⌃ ——option Z字加一杠⇧——Shift
- 多个按键点击映射到同一个消息函数中的方法(ON_COMMAND_RANGE)