采用hihoCoder测试系统,最长回文子串
实现中分别对比了string和char*,并且实现了经典的Manacher算法,不过发现Manacher算法并非最快的,可能因为涉及到字符串的生成问题吧。
注意LongestPalindrome2中的实现技巧。先寻找当前字符相同的字符,并且更新index,从而提高效率。
不过也遇到一个问题,在本地环境下,getchar+gets可以完成输入,并得到正确的结果,但是在hihoCoder的系统中,会提示wrong answer。经测试发现,问题出在getchar上。scanf(“%d\n”, &n) + gets这样也没有问题了。暂时不清楚原因。怀疑与编译器有关(G++)?
Manacher算法,理解了的话,还是很简单的,把奇偶转换为只考虑奇数的情况,然后利用之前计算出的结果以提升效率。想清楚如何利用就好了。
#include <iostream>
#include <string>
#include <cstdio>
#include <algorithm>
#include <cstring> // strlen
using namespace std;
// 260ms 8MB
int LongestPalindrome1(const string &);
// 35ms 7MB
int LongestPalindrome2(const char *);
// Manacher
// 106ms 17MB
void format(char *, const char *);
int LongestPalindrome3(int *, const char *);
const int N = 1000002;
char s[N], str[2 * N];
int P[2 * N];
int main() {
int n;
cin >> n;
/*string s;
while (n--) {
cin >> s;
cout << LongestPalindrome1('$' + s) << endl;
}*/
getchar();
//s[0] = '$';
//while (n--) {
// //gets(s + 1); // wrong answer????
// scanf("%s", s + 1);
// cout << LongestPalindrome2(s) << endl;
//}
while (n--) {
scanf("%s", s);
format(str, s);
cout << LongestPalindrome3(P, str) << endl;
}
return 0;
}
int LongestPalindrome1(const string &str) {
int size = str.size();
int maxLen = 0;
for (int i = 1, s, e, t; i < size; ++i) {
s = i;
e = i;
while (e + 1 < size && str[e + 1] == str[i]) {
++e;
}
i = e;
while (e + 1 < size && str[s - 1] == str[e + 1]) {
--s;
++e;
}
if ((t = e - s + 1) > maxLen) {
maxLen = t;
}
}
return maxLen;
}
int LongestPalindrome2(const char *str) {
int maxLen = 0;
for (int i = 1, left, right; str[i]; ++i) {
left = i;
right = i;
while (str[right + 1] == str[i]) {
++right;
}
i = right;
while (str[left - 1] == str[right + 1]) {
--left;
++right;
}
int t = right - left + 1;
if (t > maxLen) {
maxLen = t;
}
}
return maxLen;
}
void format(char *str, const char *s) {
str[0] = '$';
str[1] = '#';
int n = 2;
for (int i = 0; s[i]; ++i) {
str[n++] = s[i];
str[n++] = '#';
}
str[n] = '\0';
}
int LongestPalindrome3(int *P, const char *str) {
int ma = 0, re;
for (int i = 1; str[i]; ++i) {
if (ma > i) {
P[i] = min(ma - i, P[2 * re - i]);
}
else {
P[i] = 1;
}
while (str[i - P[i]] == str[i + P[i]]) {
++P[i];
}
if (P[i] + i > ma) {
ma = P[i] + i;
re = i;
}
}
int ans = 0;
for (int i = 0; i < strlen(str); ++i) {
ans = max(ans, P[i] - 1);
}
return ans;
}