hdu 3068 最长回文

本文深入解析Manacher算法的核心思想及其在处理最长回文串问题中的应用,通过实例代码演示如何实现这一经典算法,以及如何优化其性能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

hdu 3068 最长回文

这是一道最长回文串Manacher的裸题;

还是先讲讲里面使用dp的思想对Manacher的理解吧!

Manacher算法就是处理出前面以id为中点,半径为Mp[id]的回文串的右边界mx;之后每次处理i时,就可以看i是否在mx内,若是在mx里面,就可以将Mp[i]的初始值设置为i关于id对称的2*id-i处的点j,这时就可以从这个基础上向左右延伸了,否则朴素的算法就是每次Mp[i]都从0开始;很容易知道当i不在前面的回文串中,就不能利用前面得到的结果, 只能从1开始;还有就是注下Ma[]的处理就行;

374MS   2652K   1041 B
#include<bits/stdc++.h>
using namespace std;
#define rep(i,n) for(int i = 1;i <= n;i++)
const int MAXN = 110011;
char Ma[MAXN<<1];
int Mp[MAXN<<1];
char ret[MAXN],s[MAXN];
void Manacher(const char s[],int len)
{
    int l = 0;
    Ma[l++] = '$';Ma[l++] = '#';
    rep(i,len){
        Ma[l++] = s[i];
        Ma[l++] = '#';
    }
    Ma[l] = '\0';
    int mx = 0,id;
    rep(i,l-1){
        Mp[i] = mx > i?min(mx-i,Mp[2*id-i]):1; // *** 
        while(Ma[i+Mp[i]] == Ma[i-Mp[i]]) Mp[i]++;
        if(i + Mp[i] > mx){
            mx = i + Mp[i];
            id = i;
        }
    }
}
int main()
{
    int len,i,j;
    while(scanf("%s",s+1) != EOF){
        len = strlen(s+1);
        Manacher(s,len);
        int ans = 0,id;
        for(i = 1;i < len*2;i++){
            if(ans < Mp[i])
                ans = Mp[i],id = i; //这里没有将 ans = Mp[i] - 1;而是在输出的时候
        }
        printf("%d\n",--ans);
        /*id = id/2 - ans/2;  // 处理输出最长回文字符串;
        if(ans%2 == 0) id++;
        for(i = 0;i < ans;i++)
            putchar(s[id++]);*/
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值