小A的回文串(牛客小白月赛13) Manacher

版权声明:转载时 别忘了注明出处 https://blog.csdn.net/ZCY19990813/article/details/89277708

链接:https://ac.nowcoder.com/acm/contest/549/B
来源:牛客网
 

题目描述

小A非常喜欢回文串,当然我们都知道回文串这种情况是非常特殊的。所以小A只想知道给定的一个字符串的最大回文子串是多少,但是小A对这个结果并不是非常满意。现在小A可以对这个字符串做一些改动,他可以把这个字符串最前面的某一段连续的字符(不改变顺序)移动到原先字符串的末尾。那么请问小A通过这样的操作之后(也可以选择不移动)能够得到最大回文子串的长度是多少。

输入描述:

一行一个字符串表示给定的字符串S一行一个字符串表示给定的字符串S

输出描述:

一行输出一个整数,表示通过这样的操作后可以得到最大回文子串的长度。

链接:https://ac.nowcoder.com/acm/contest/549/B
来源:牛客网
 

示例1

输入

dcbaabc

输出

7

说明

将前面的dcba移动到末尾变成abcdcba,这个字符串的最大回文子串就是它本身,长度为7

备注:

N表示字符串的长度,1≤N≤5000

思路:数据量较小,直接暴力求解,将字符串移动len次,每次都遍历。那问题来了,怎么求一个字符串中最长的回文子串呢,那就用到Manacher了。

先来一个Manacher的模板:

const int MAXN=110010;
char Ma[MAXN*2];
int Mp[MAXN*2];
void Manacher(char s[],int len)
{
    int l=0;
    Ma[l++]='$';
    Ma[l++]='#';
    for(int i=0; i<len; i++)
    {
        Ma[l++]=s[i];
        Ma[l++]='#';
    }
    Ma[l]=0;
    int mx=0,id=0;
    for(int i=0; i<l; i++)
    {
        Mp[i]=mx>i?min(Mp[2*id − i],mx − i):1;
        while(Ma[i+Mp[i]]==Ma[i − Mp[i]])Mp[i]++;
        if(i+Mp[i]>mx)
        {
            mx=i+Mp[i];
            id=i;
        }
    }
}
/*
* abaaba
* i:
0 1 2 3 4 5 6 7 8 9 10 11 12 13
* Ma[i]: $ # a # b # a # a # b # a #
* Mp[i]: 1 1 2 1 4 1 2 7 2 1 4 1 2 1
*/
char s[MAXN];
int main()
{
    while(scanf("%s",s)==1)
    {
        int len=strlen(s);
        Manacher(s,len);
        int ans=0;
        for(int i=0; i<2*len+2; i++)
            ans=max(ans,Mp[i] − 1);
        printf("%d\n",ans);
    }
    return 0;
}

 AC代码:

#include <iostream>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <vector>
#include <map>
#include <string>
#include <deque>
#include <queue>
#include <cstdio>
#include <cstdlib>
#include <set>
#define MAX 0x3f3f3f3f
using namespace std;
typedef long long ll;
const int MAXN=1e4+10;
priority_queue <int,vector<int>,greater<int> > q;
char Ma[MAXN*2];
int Mp[MAXN*2];
void Manacher(char s[],int len)
{
    int l=0;
    Ma[l++]='$';
    Ma[l++]='#';
    for(int i=0; i<len; i++)
    {
        Ma[l++]=s[i];
        Ma[l++]='#';
    }
    Ma[l]=0;
    int mx=0,id=0;
    for(int i=0; i<l; i++)
    {
        Mp[i]=mx>i?min(Mp[2*id - i],mx - 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()
{
    char s[MAXN],ss[MAXN];
    cin>>s;
    int len=strlen(s);
    for(int i=0;i<len;i++)
        ss[i]=s[i];
    int maxx=-1;
    for(int k=0;k<len;k++)
    {
        //cout<<ss<<endl;
        memset(Mp,0,sizeof(Mp));
        memset(Ma,0,sizeof(Ma));
        Manacher(ss,len);
        int ans=0;
        for(int i=0; i<2*len+2; i++)
            ans=max(ans,Mp[i] - 1);
        //cout<<ss<<endl;
       // cout<<ans<<endl;
        if(ans>=maxx)
            maxx=ans;
        char c=ss[0];
        for(int i=1;i<len;i++)
            ss[i-1]=ss[i];
        ss[len-1]=c;
    }
    cout<<maxx<<endl;
    return 0;
}

猜你喜欢

转载自blog.csdn.net/ZCY19990813/article/details/89277708