HDU 3068 (Manacher) 最长回文

时间:2021-08-29 20:44:14

求一个字符串的最长子串,Manacher算法是一种O(n)的算法,很给力!

s2[0] = '$',是避免在循环中对数组越界的检查。

老大的代码:

http://www.cnblogs.com/BigBallon/p/3816890.html

详细的图解:

http://blog.csdn.net/xingyeyongheng/article/details/9310555

模板题,没有什么好说的。Manacher算法本身确实是要好好理解体会的。

 #define LOCAL
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std; const int maxn = + ;
char s1[maxn], s2[maxn * ];
int p[maxn * ]; void init(char s1[], char s2[])
{
s2[] = '$', s2[] = '#';
int j = ;
for(int i = ; s1[i] != '\0'; ++i)
{
s2[j++] = s1[i];
s2[j++] = '#';
}
s2[j] = '\0';
} void manacher(char s[])
{
int id, mx = ;
p[] = ;
for(int i = ; s[i] != '\0'; ++i)
{
if(mx > i)
p[i] = min(p[*id-i], mx - i);
else
p[i] = ;
while(s[i+p[i]] == s[i-p[i]])
++p[i];
if(i + p[i] > mx)
{
mx = i + p[i];
id = i;
}
}
} void getans(void)
{
int ans = ;
for(int i = ; s2[i] != '\0'; ++i)
ans = max(ans, p[i] - );
printf("%d\n", ans);
} int main(void)
{
#ifdef LOCAL
freopen("3068in.txt", "r", stdin);
#endif while(scanf("%s", s1) != EOF)
{
init(s1, s2);
manacher(s2);
getans();
}
return ;
}

代码君