时间限制:1000ms
单点时限:1000ms
内存限制:64MB

描述

小Hi和小Ho是一对好朋友,出生在信息化社会的他们对编程产生了莫大的兴趣,他们约定好互相帮助,在编程的学习道路上一同前进。

这一天,他们遇到了一连串的字符串,于是小Hi就向小Ho提出了那个经典的问题:“小Ho,你能不能分别在这些字符串中找到它们每一个的最长回文子串呢?”

小Ho奇怪的问道:“什么叫做最长回文子串呢?”

小Hi回答道:“一个字符串中连续的一段就是这个字符串的子串,而回文串指的是12421这种从前往后读和从后往前读一模一样的字符串,所以最长回文子串的意思就是这个字符串中最长的身为回文串的子串啦~”

小Ho道:“原来如此!那么我该怎么得到这些字符串呢?我又应该怎么告诉你我所计算出的最长回文子串呢?

小Hi笑着说道:“这个很容易啦,你只需要写一个程序,先从标准输入读取一个整数N(N<=30),代表我给你的字符串的个数,然后接下来的就是我要给你的那N个字符串(字符串长度<=10^6)啦。而你要告诉我你的答案的话,只要将你计算出的最长回文子串的长度按照我给你的顺序依次输出到标准输出就可以了!你看这就是一个例子。”

提示一 提示二 提示三 提示四

样例输入
3
abababa
aaaabaa
acacdas
样例输出
7
5
3

传说中的Manacher算法,算法的核心就在这一句上了:p[i] = min(p[2*id-i], p[id] + id - i);

原文地址:
http://zhuhongcheng.wordpress.com/2009/08/02/a-simple-linear-time-algorithm-for-finding-longest-palindrome-sub-string/
    其实原文说得是比较清楚的,只是英文的,我这里写一份中文的吧。
    首先:大家都知道什么叫回文串吧,这个算法要解决的就是一个字符串中最长的回文子串有多长。这个算法可以在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开始的)

if( mx > i)
    p[i]=MIN( p[2*id-i], mx-i);
 
就是当前面比较的最远长度mx>i的时候,P[i]有一个最小值。这个算法的核心思想就在这里,为什么P数组满足这样一个性质呢?
   (下面的部分为图片形式)

 #include <bits/stdc++.h>
using namespace std; int N;
string s; void solve() {
string s1;
s1.resize( * s.size() + );
s1[] = '$';
s1[] = '#';
for (int i = ; i < s.size(); ++i) {
s1[(i + ) << ] = s[i];
s1[((i + ) << ) + ] = '#';
}
vector<int> p(s1.size(), );
int res = ;
for (int id = , i = ; i < s1.size(); ++i) {
if (p[id] + id > i) p[i] = min(p[2 * id - i], p[id] + id - i);
else p[i] = ;
while (s1[i + p[i]] == s1[i - p[i]]) ++p[i];
if (i + p[i] > id + p[id]) id = i;
res = max(res, p[i]);
}
cout << res - << endl;
} int main() {
cin >> N;
while (N--) {
cin >> s;
solve();
}
return ;
}

[hihoCoder] #1032 : 最长回文子串的更多相关文章

  1. hihocoder #1032 : 最长回文子串【 manacher算法实现 】

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

  2. hihoCoder #1032 : 最长回文子串 [ Manacher算法--O(n)回文子串算法 ]

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

  3. hihocoder #1032 : 最长回文子串 Manacher算法

    题目链接: https://hihocoder.com/problemset/problem/1032?sid=868170 最长回文子串 时间限制:1000ms内存限制:64MB 问题描述 小Hi和 ...

  4. hihocoder 1032 最长回文子串(Manacher)

    传送门 #include<queue> #include<cmath> #include<cstdio> #include<cstring> #incl ...

  5. hiho #1032: 最长回文子串

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

  6. hihoCoder hiho一下 第一周 #1032 : 最长回文子串 (Manacher)

    题意:给一个字符串,求最长回文子串的长度. 思路: (1)暴力穷举.O(n^3) -----绝对不行. 穷举所有可能的出现子串O(n^2),再判断是否回文O(n).就是O(n*n*n)了. (2)记录 ...

  7. hihocode #1032 : 最长回文子串【manacher】模板题

    题目链接:https://vjudge.net/problem/HihoCoder-1032 manacher算法详解:https://blog.csdn.net/dyx404514/article/ ...

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

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

  9. hihoCoder week1 最长回文子串

    题目链接 https://hihocoder.com/contest/hiho1/problem/1 做法 Manacher #include <bits/stdc++.h> using ...

随机推荐

  1. 【C#】利用JMail发送邮件

    有用到需要发送帐号激活邮件,利用Jmail去做蛮简单的,先记录下: 1.首先到Jmail官网下载对应的版本,解压后安装(Jmail 4.4 免费版). 2.到安装目录就可以找到jmail.dll文件, ...

  2. C#.NET常见问题(FAQ)-想要另存一个项目,sln文件丢了怎么办,如何打开高版本的项目

    如下图所示,我想要另存一个工程,把 V4.4整个的项目另存为V4.5,我可以把解决方案文件(.sln)改名字,但是我没法把文件夹改名字,改了打开sln就说找不到.   很简单的一个思路是反正sln是多 ...

  3. Python中参数多个值的表示法

    今天在写Python脚本时,调用了数据管理-制图综合-融合工具,在ArcGIS里操作的参数设置如下: 如果融合字段只有一个那好办,如果融合字段有多个我该怎么表达,查看帮助文档中的示例代码明白了: 所以 ...

  4. 谈谈Boost网络编程(2)—— 新系统的设计

    写文章之前.我们一般会想要採用何种方式,是"开门见山",还是"疑问式开头".写代码也有些类似.在编码之前我们须要考虑系统总体方案,这也就是各种设计文档的作用.在 ...

  5. nginx 备忘

    下载 start nginxlocalhost:80

  6. plsql 存储过程 测试

      plsql 存储过程 测试 CreationTime--2018年8月14日09点54分 Author:Marydon 1.找到要运行的存储过程-->选中-->右键-->测试 2 ...

  7. 〖Linux〗zigbee实验之cc2430移植tinyos2.x的步骤(Ubuntu13.10)

    开发环境:Ubuntu13.10 1. 添加源,并安装tinyos-2.11:sudo gedit  /etc/apt/sources.list #往里边添加deb http://tinyos.sta ...

  8. 感谢CSDN赠送的图书和杂志(5月份)

    互联网的精神就是开放.就是分享.在分享的同一时候.我们也会收获到意外的回报. 近期.因为我在5月份发表了14篇博文,因此CSDN赠送了一本图书<软件系统架构>(本人自己选的)和一本< ...

  9. [Done]ftp使用小结

    基本命令: put 本地文件名 ftp文件名 get ftp文件名 本地文件名 mget ftp文件多个文件  注意使用该命令时先用 lcd切换本地路径 还有一些常用的  ls mkdir 等,参考 ...

  10. python学习笔记之基础数据和控制

    注释: 单行注释 # 多行注释'''    ''' 注意:当注释中有汉字时需要在python文件的第一行添加如下内容之一:#coding:gbk或#coding:utf-8或##-*- coding ...