题意:给出一个字符串,求出最长回文字串。

思路:一开始我直接上了后缀数组DC3的解法,然后MLE了。看了DISCUSS发现还有一种计算回文字串更加优越的算法,就是manacher算法。就去学习了一下,

/************************以下转自http://funnyxj.blog.163.com/blog/static/20459016020127514231538/********************/

这个算法要解决的就是一个字符串中最长的回文子串有多长。这个算法可以在O(n)的时间复杂度内既线性时间复杂度的情况下,求出以每个字符为中心的最长回文有多长,
这个算法有一个很巧妙的地方,它把奇数的回文串和偶数的回文串统一起来考虑了。这一点一直是在做回文串问题中时比较烦的地方。这个算法还有一个很好的地方就是充分利用了字符匹配的特殊性,避免了大量不必要的重复匹配。
算法大致过程是这样。先在每两个相邻字符中间插入一个分隔符,当然这个分隔符要在原串中没有出现过。一般可以用‘#’分隔。这样就非常巧妙的将奇数长度回文串与偶数长度回文串统一起来考虑了(见下面的一个例子,回文串长度全为奇数了),然后用一个辅助数组P记录以每个字符为中心的最长回文串的信息。P[id]记录的是以字符str[id]为中心的最长回文串,当以str[id]为第一个字符,这个最长回文串向右延伸了P[id]个字符。
原串: w aa bwsw f d
新串: # w# a # a # b# w # s # w # f # d #
辅助数组P: 1 2 1 2 3 2 1 2 1 2 1 4 1 2 1 2 1 2 1
这里有一个很好的性质,P[id]-1就是该回文子串在原串中的长度(包括‘#’)。如果这里不是特别清楚,可以自己拿出纸来画一画,自己体会体会。当然这里可能每个人写法不尽相同,不过我想大致思路应该是一样的吧。
好,我们继续。现在的关键问题就在于怎么在O(n)时间复杂度内求出P数组了。只要把这个P数组求出来,最长回文子串就可以直接扫一遍得出来了。
由于这个算法是线性从前往后扫的。那么当我们准备求P[i]的时候,i以前的P[j]我们是已经得到了的。我们用mx记在i之前的回文串中,延伸至最右端的位置。同时用id这个变量记下取得这个最优mx时的id值。(注:为了防止字符比较的时候越界,我在这个加了‘#’的字符串之前还加了另一个特殊字符‘$’,故我的新串下标是从1开始的)
/********************************************************************************************************************************/

CODE:

#include <set>
#include <map>
#include <stack>
#include <cmath>
#include <queue>
#include <cstdio>
#include <string>
#include <vector>
#include <iomanip>
#include <cstring>
#include <iostream>
#include <algorithm>
#define Max 2505
#define FI first
#define SE second
#define ll long long
#define PI acos(-1.0)
#define inf 0x3fffffff
#define LL(x) ( x << 1 )
#define bug puts("here")
#define PII pair<int,int>
#define RR(x) ( x << 1 | 1 )
#define mp(a,b) make_pair(a,b)
#define mem(a,b) memset(a,b,sizeof(a))
#define REP(i,s,t) for( int i = ( s ) ; i <= ( t ) ; ++ i )
#define N 2000055
using namespace std; char s[N] ;
char str[N] ;
int rad[N] ;
int manacher () {
int len = strlen(s) ;
int max = 0;
str[0] = '$';
str[1] = '#';
int i = 0 ;
for (; i < len; i++) {
str[i * 2 + 2] = s[i];
str[i * 2 + 3] = '#';
}
str[2 * len + 2] = 0;
for (int i = 1; i < 2 * len + 2 ; i++) {
rad[i] = 0;
}
int id = 0;
for (i = 1; i < 2 * len + 2; i++) {
if (max > i)
rad[i] = min(rad[2 * id - i], rad[id] + id - i) ;
else
rad[i] = 1 ;
while (str[i + rad[i]] == str[i - rad[i]])
rad[i] ++ ;
if (rad[i] + i > max) {
max = rad[i] + i;
id = i;
}
}
int mx = 0;
for (i = 1; i < 2 * len + 2 ; i++) {
if (mx < rad[i] - 1)
mx = rad[i] - 1;
}
return mx;
} int main() {
int ca = 0 ;
while(scanf("%s",s) != EOF) {
if(strcmp(s , "END") == 0)break ;
printf("Case %d: " , ++ ca) ;
printf("%d\n",manacher()) ;
}
return 0 ;
}

POJ 3974 最长回文字串(manacher算法)的更多相关文章

  1. 最长回文字串——manacher算法

    时间复杂度:O(n) 参考:https://segmentfault.com/a/1190000003914228 1.问题定义 最长回文子串问题:给定一个字符串,求它的最长回文子串长度. 如果一个字 ...

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

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

  3. Palindrome(最长回文串manacher算法)O(n)

     Palindrome Time Limit:15000MS     Memory Limit:65536KB     64bit IO Format:%I64d & %I64u Submit ...

  4. poj_1974,最长回文字串manacher

    时间复杂度为O(n),参考:http://bbs.dlut.edu.cn/bbstcon.php?board=Competition&gid=23474 #include<iostrea ...

  5. 求字符串的最长回文字串 O(n)

    昨天参加了某公司的校园招聘的笔试题,做得惨不忍睹,其中就有这么一道算法设计题:求一个字符串的最长回文字串.我在ACM校队选拔赛上遇到过这道题,当时用的后缀数组AC的,但是模板忘了没写出代码来. 回头我 ...

  6. hihocoder 第一周 最长回文字串

    题目1 : 最长回文子串 时间限制:1000ms 单点时限:1000ms 内存限制:64MB 描述 小Hi和小Ho是一对好朋友,出生在信息化社会的他们对编程产生了莫大的兴趣,他们约定好互相帮助,在编程 ...

  7. 最长回文子串—Manacher 算法 及 python实现

    最长回文子串问题:给定一个字符串,求它的最长回文子串长度.如果一个字符串正着读和反着读是一样的,那它就是回文串.   给定一个字符串,求它最长的回文子串长度,例如输入字符串'35534321',它的最 ...

  8. HiHo 1032 最长回文子串 (Manacher算法求解)

    /** * 求解最长回文字串,Manacher算法o(n)求解最长回文子串问题 **/ #include<cstdio> #include<cstdlib> #include& ...

  9. luoguP4555 [国家集训队]最长双回文串 manacher算法

    不算很难的一道题吧.... 很容易想到枚举断点,之后需要处理出以$i$为开头的最长回文串的长度和以$i$为结尾的最长回文串的长度 分别记为$L[i]$和$R[i]$ 由于求$R[i]$相当于把$L[i ...

随机推荐

  1. 我的Python成长之路---第一天---Python基础(2)---2015年12月26日(雾霾)

    三.数据类型 Python基本类型(能够直接处理的数据类型有以下几种)主要有5种 1.整数(int) Python可以处理任意大小的整数,当然包括负整数,在程序中的表示方法和数学上的写法一模一样,例如 ...

  2. C-整数划分

    将正整数 n 表示成一系列正整数之和, n=n1+n2+…+nk, 其中 n1>=n2>=…>=nk>=1 , k>=1 . 正整数 n 的这种表示称为正整数 n 的划分 ...

  3. Mac删除废纸篓中的单一文件和文件夹

    http://www.macappbox.com/tips/159/ 通过Automator创建教程: 1.打开Automator并选择新建 2.选择服务类型 3.搜索Run Shell Script ...

  4. XP里面其实也讲究admin的执行权限

    错误的方法:比如说,当前登录帐号cliff是管理员,此时直接运行cmd,输入: net user administrator 123 结果说这个用户找不到. --------------------- ...

  5. PHP - 拒绝低版本PHP

    //判断PHP版本是否太低 if (PHP_VERSION < '4.1.0') { echo 'Version is to Low!'; exit; }

  6. wcf 出现 IsContentTypeSupported 错误

    查看添加的服务地址是不是https开头的,而 *.config 文件里面自动添加的链接变成了http,当前的bindbing类型为basicHttpBinding, 解决方法:在config文件里面手 ...

  7. jquery mobile自己定义webapp开发实例(一)——前言篇

    用jquery mobile做了一段时间的webapp开发,准备用自己的一个小demo做一个模块化的分享 点击demo演示 手机演示二维码: 此demo已经是比較老的版本号,用户体验流畅度确实还存在非 ...

  8. (摘录)MSMQ的简单介绍

    MSMQ(MicroSoft  Message  Queue,微软消息队列)是在多个不同的应用之间实现相互通信的一种异步传输模式,相互通信的应用可以分布于同一台机器上,也可以分布于相连的网络空间中的任 ...

  9. 1.0.1-学习Opencv与MFC混合编程之---播放AVI视频

    资源源代码:http://download.csdn.net/detail/nuptboyzhb/3961639 版本1.0.1新增内容 Ø  新建菜单项,Learning OpenCV——> ...

  10. redhat6.3+oracle11GR2 单库 安装规划

    oracle11g单实例安装+redhat6.3   规划 一.查看环境 [root@JSCS78DB dev]# cat /etc/redhat-release Red Hat Enterprise ...