hdu 3068 最长回文(马拉车)
Posted jpphy0
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了hdu 3068 最长回文(马拉车)相关的知识,希望对你有一定的参考价值。
问题
hdu 3068 最长回文 - https://acm.hdu.edu.cn/showproblem.php?pid=3068
分析
- 暴力搜索(tle)
- 马拉车O(n)
代码
- 暴力搜索
#include<bits/stdc++.h>
using namespace std;
const int MXN = 1e5+10;
char s[MXN];
int expand(int l, int r){ // 扩展
while(s[l] && s[r] && s[l] == s[r]) --l, ++r;
return r - l - 1;
}
int main(){
int t, l, r, ans;
scanf("%d", &t);
while(t--){
scanf("%s", s+1), s[0] = '\\0';
l = 1, r = 1, ans = 0;
while(s[l] && s[r]) // 两种扩展方式的初始条件:l == r 或者 r == l+1
ans = max(ans, expand(l, r)), l == r ? ++r : ++l;
printf("%d\\n", ans);
}
return 0;
}
- Manacher(马拉车)
/* hdu 3068 最长回文 */
#include<bits/stdc++.h>
using namespace std;
const int MXN = 1.1e5+10;
char s[MXN<<1];
int R; // R是递推过程中所有出现过的对称区间的最大右边界
int p; // 与R对应的对称中心
int len[MXN<<1]; // len[i]:最大回文长度,i是回文串的对称中心(变换后的字符串)
int manacher(int n){
int res = 0;
for(int l, r, i = 1; i <= n; ++i){// l,r是以i为中心的对称边界
if(i >= R) l = i, r = i; // i是对称中心,也是对称边界
else r = min(R, i + len[(p<<1)-i]), l = (i << 1) - r;// 设定对称边界
while(s[l-1] && s[r+1] && s[l-1] == s[r+1]) ++r, --l;// 暴力扩展
if(r >= R) R = r, p = i; // 更新最大右边界及对称中心
len[i] = (r - l + 1) >> 1;
res = max(res, len[i]);
}
return res;
}
int main(){
int n;
while(scanf("%s", s+MXN) == 1){
n = strlen(s+MXN)+1, s[0] = '\\0'; // 设定一个结束符,用于扩展时比较
for(int i = 1; i <= n; ++i) s[2*i-1] = '#', s[i<<1] = s[i+MXN-1];//变换字符串
--n, p = 0, R = 0, len[0] = 0;
printf("%d\\n", manacher(n<<1|1));
}
return 0;
}
以上是关于hdu 3068 最长回文(马拉车)的主要内容,如果未能解决你的问题,请参考以下文章