【每日一题(31)】马拉车算法(最长回文子串 HihoCoder - 1032)(最长回文 HDU-3068)

最长回文子串 HihoCoder - 1032

Time Limit:1000ms
Case Time Limit:1000ms
Memory Limit:64MB

Problem Description

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

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

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

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

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

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

Sample Input

3
abababa
aaaabaa
acacdas

Sample Output

7
5
3

code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
#include<iostream>
#include<cstdio>
#include<cstring>
#include<vector>
using namespace std;
#define maxn 200000000
char str[maxn],s[maxn];
int main()
{
int n;
scanf("%d",&n);
getchar();
while(n--){
scanf("%s",s);
int cnt = 0;
str[cnt++] = '$';str[cnt++] = '#';
int len1 = strlen(s);
for(int i = 0;i < len1; i++){
str[cnt++] = s[i];
str[cnt++] = '#';
}
str[cnt] = '\0';
//cout << str << endl;//
int len = strlen(str);
vector<int> p(len + 1,0);
int mi = 0,right = 0,maxlen = 0;
for(int i = 1;i < len; i++){
p[i] = right > i?min(p[2*mi - i],right - i):1;
while(str[i - p[i]] == str[i + p[i]]){
p[i]++;
}
if(i + p[i] > right){
mi = i;
right = i + p[i];
}
if(p[i] > maxlen){
maxlen = p[i];
}
}
printf("%d\n",maxlen - 1);
}

return 0;
}

最长回文 hdu-3068

Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 26731 Accepted Submission(s): 9773

Problem Description

给出一个只由小写英文字符a,b,c…y,z组成的字符串S,求S中最长回文串的长度.
回文就是正反读都是一样的字符串,如aba, abba等

Input

输入有多组case,不超过120组,每组输入为一行小写英文字符a,b,c…y,z组成的字符串S
两组case之间由空行隔开(该空行不用处理)
字符串长度len <= 110000

Output

每一行一个整数x,对应一组case,表示该组case的字符串中所包含的最长回文长度.

Sample Input

aaaa

abab

Sample Output

4
3

Source

2009 Multi-University Training Contest 16 - Host by NIT

code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
#include<iostream>
#include<cstdio>
#include<cstring>
#include<vector>
using namespace std;
#define maxn 500000
char str[maxn],s[maxn];
int main()
{
while(~scanf("%s",s)){
int cnt = 0;
str[cnt++] = '$';str[cnt++] = '#';
int len1 = strlen(s);
for(int i = 0;i < len1; i++){
str[cnt++] = s[i];
str[cnt++] = '#';
}
str[cnt] = '\0';
//cout << str << endl;//
int len = strlen(str);
vector<int> p(len + 1,0);
int mi = 0,right = 0,maxlen = 0;
for(int i = 1;i < len; i++){
p[i] = right > i?min(p[2*mi - i],right - i):1;
while(str[i - p[i]] == str[i + p[i]]){
p[i]++;
}
if(i + p[i] > right){
mi = i;
right = i + p[i];
}
if(p[i] > maxlen){
maxlen = p[i];
}
}
printf("%d\n",maxlen - 1);
getchar();
}

return 0;
}