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

传送门

#1032 : 最长回文子串

时间限制: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算法--O(n)回文子串算法

直接转一个大牛的思路,讲的很好:

http://blog.csdn.net/ggggiqnypgjg/article/details/6645824/

http://acm.hust.edu.cn/vjudge/problem/viewSource.action?id=140283

结果:Accepted      提交时间:2015-05-07 14:11:06

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <iostream>
 4 #include <algorithm>
 5 #include <stack>
 6 #include <cctype>
 7 #include <vector>
 8 #include <cmath>
 9
10 #define ll long long
11
12 using namespace std;
13
14 const int M = 21;
15 const int N = 1000010;
16 const ll mod = 1000000007;
17
18 int T;
19 char te[N];
20 char s[2*N];
21 int p[2*N];
22 int ans;
23 int l;
24
25 void pre()  //为了防止字符比较的时候越界,我在这个加了‘#’的字符串之前还加了另一个特殊字符‘$’,故我的新串下标是从1开始的
26 {
27     int l1=strlen(te);
28     l=2*l1+2;
29     s[0]=‘$‘;
30     s[1]=‘#‘;
31     for(int i=0;i<l1;i++){
32         s[i*2+2]=te[i];
33         s[i*2+3]=‘#‘;
34     }
35     s[l]=‘\0‘;
36 }
37
38 void Manacher()
39 {
40     int i,mx,id;    //我们用mx记在i之前的回文串中,延伸至最右端的位置。同时用id这个变量记下取得这个最优mx时的id值。
41     mx=0;
42     for(i=1;i<l;i++){
43         if(mx>i){
44             p[i]=min(p[2*id-i],mx-i);
45         }
46         else{
47             p[i]=1;
48         }
49         for(;s[ i+p[i] ]==s[ i-p[i] ];p[i]++){
50             if(i+p[i]>mx){
51                 mx=i+p[i];
52                 id=i;
53             }
54         }
55     }
56 }
57
58 int main()
59 {
60     //freopen("data.in","r",stdin);
61     scanf("%d",&T);
62     for(int ccnt=1;ccnt<=T;ccnt++){
63     //while(scanf("%d%d",&a,&b) != EOF) {
64         scanf("%s",te);
65         pre();
66         Manacher();
67         int i;
68         ans=1;
69         for(i=1;i<l;i++){
70             ans=max(ans,p[i]-1);
71         }
72         printf("%d\n",ans);
73     }
74     return 0;
75 }
时间: 2024-10-11 23:30:50

hihoCoder #1032 : 最长回文子串 [ Manacher算法--O(n)回文子串算法 ]的相关文章

hihoCoder - 1032 - 最长回文子串 (字符串~)

#1032 : 最长回文子串 时间限制:1000ms 单点时限:1000ms 内存限制:64MB 描述 小Hi和小Ho是一对好朋友,出生在信息化社会的他们对编程产生了莫大的兴趣,他们约定好互相帮助,在编程的学习道路上一同前进. 这一天,他们遇到了一连串的字符串,于是小Hi就向小Ho提出了那个经典的问题:"小Ho,你能不能分别在这些字符串中找到它们每一个的最长回文子串呢?" 小Ho奇怪的问道:"什么叫做最长回文子串呢?" 小Hi回答道:"一个字符串中连续的一

hihocoder 1032 : 最长回文子串(Manacher)

之前做过类似的题,只是理解了,还没达到驾轻就熟,想到即敲出的地步,所以再练一次. 顺带将Manacher算法思想解释一遍,加强印象,也算作分享吧. Manacher 我们用f(x)表示以x位置为中心的回文串的长度 j相对i的对应位置是j' 那么f(j)与f(j')和f(i)有什么关系呢. 先看第一张图,下面那条横杠表示f(i),那么,既然j'与j相对应,j'的回文串长度已经求出,那么j位置的回文串长度一定是大于等于j'长度的. 即f(i) >= f(j')=f(i*2-j) 但是还存在上图这样的

hihoCoder #1032 最长回文子串

1 #include <iostream> 2 #include <string> 3 #include <vector> 4 #include <algorithm> 5 6 using namespace std; 7 8 void even_to_odd(string &init) { 9 init.insert(init.begin(),'('); 10 for (auto i = init.begin() + 1; i != init.en

hiho#1032 : 最长回文子串 (manacher算法O(n)时间求字符串的最长回文子串 )

#1032 : 最长回文子串 时间限制:1000ms 单点时限:1000ms 内存限制:64MB 描述 小Hi和小Ho是一对好朋友,出生在信息化社会的他们对编程产生了莫大的兴趣,他们约定好互相帮助,在编程的学习道路上一同前进. 这一天,他们遇到了一连串的字符串,于是小Hi就向小Ho提出了那个经典的问题:"小Ho,你能不能分别在这些字符串中找到它们每一个的最长回文子串呢?" 小Ho奇怪的问道:"什么叫做最长回文子串呢?" 小Hi回答道:"一个字符串中连续的一

#1032 : 最长回文子串 (Manacher算法)

这篇博文对Manacher讲的还不错 #1032 : 最长回文子串 时间限制:1000ms 单点时限:1000ms 内存限制:64MB 描述 小Hi和小Ho是一对好朋友,出生在信息化社会的他们对编程产生了莫大的兴趣,他们约定好互相帮助,在编程的学习道路上一同前进. 这一天,他们遇到了一连串的字符串,于是小Hi就向小Ho提出了那个经典的问题:"小Ho,你能不能分别在这些字符串中找到它们每一个的最长回文子串呢?" 小Ho奇怪的问道:"什么叫做最长回文子串呢?" 小Hi回

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

Manacher算法o(n)求解最长回文子串问题 非常巧妙 #include<bits/stdc++.h> using namespace std; char str[2000020],s[2000020]; int p[2000020]; int len,id,mx; void pre() //对字符串进行预处理 { len=strlen(s); str[0]='$'; str[1]='#'; for(int i=0;i<len;i++) { str[i*2+2]=s[i]; str[

hihoCoder hiho一下 第一周 #1032 : 最长回文子串 (特殊处理)

思路: (1)暴力穷举.O(n^3) -----绝对不行. 穷举所有可能的出现子串O(n^2),再判断是否回文O(n).就是O(n*n*n)了. (2)记录位置.O(n^3) -----绝对不行. 先扫一遍,记录每个字符在上一次出现的位置pos.每次考虑第i个字符,如果回文子串包括 i 的话,那么肯定在i的前面有一个跟第i个字符是一样的,利用之前记录的位置pos[i]可以找到与第i个相同的字符,如果i-pos[i]比之前发现的最长的子串max还短,那么不用比较了.如果更前面还有和第i个字符一样的

hiho #1032: 最长回文子串

#1032 : 最长回文子串 时间限制:1000ms 单点时限:1000ms 内存限制:64MB 描述 小Hi和小Ho是一对好朋友,出生在信息化社会的他们对编程产生了莫大的兴趣,他们约定好互相帮助,在编程的学习道路上一同前进. 这一天,他们遇到了一连串的字符串,于是小Hi就向小Ho提出了那个经典的问题:“小Ho,你能不能分别在这些字符串中找到它们每一个的最长回文子串呢?” 小Ho奇怪的问道:“什么叫做最长回文子串呢?” 小Hi回答道:“一个字符串中连续的一段就是这个字符串的子串,而回文串指的是1

#1032 : 最长回文子串

描述 小Hi和小Ho是一对好朋友,出生在信息化社会的他们对编程产生了莫大的兴趣,他们约定好互相帮助,在编程的学习道路上一同前进. 这一天,他们遇到了一连串的字符串,于是小Hi就向小Ho提出了那个经典的问题:“小Ho,你能不能分别在这些字符串中找到它们每一个的最长回文子串呢?” 小Ho奇怪的问道:“什么叫做最长回文子串呢?” 小Hi回答道:“一个字符串中连续的一段就是这个字符串的子串,而回文串指的是12421这种从前往后读和从后往前读一模一样的字符串,所以最长回文子串的意思就是这个字符串中最长的身