您的位置:首页 > 其它

[HDOJ3068]最长回文

2015-08-29 15:06 253 查看
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3068

最长回文

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


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

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

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

[align=left]Sample Input[/align]

aaaa

abab

[align=left]Sample Output[/align]

4
3

Manacher算法的模版题,刚模仿着写了个,趁热用一下

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <iostream>
#include <cmath>
#include <queue>
#include <map>
#include <stack>
#include <list>
#include <vector>

using namespace std;

const int maxn = 1000010;
int pre[maxn];
char str[maxn];
char tmp[maxn*2];

inline int min(int x, int y) {
return x < y ? x : y;
}

int init(char *tmp, char *str) {
int len = strlen(str);
tmp[0] = '$';
for(int i = 0; i <= len; i++) {
tmp[2*i+1] = '#';
tmp[2*i+2] = str[i];
}
tmp[2*len+2] = 0;
len = 2 * len + 2;
return len;
}

void manacher(int *pre, char *tmp, int len) {
int id = 0;
int mx = 0;
for(int i = 1; i < len; i++) {
pre[i] = mx > i ? min(pre[2*id-i], mx-i) : 1;
while(tmp[i+pre[i]] == tmp[i-pre[i]]) {
pre[i]++;
}
if(pre[i] + i > mx) {
id = i;
mx = pre[i] + id;
}
}
}

int main() {
// freopen("in", "r", stdin);
while(~scanf("%s", str)) {
memset(pre, 0, sizeof(pre));
memset(tmp, 0, sizeof(tmp));
int len = init(tmp, str);
manacher(pre, tmp, len);
int ans = 1;
for(int i = 0; i < len; i++) {
ans = max(ans, pre[i]);
}
printf("%d\n", ans - 1);
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: