• 小白月赛13 B小A的回文串 (马拉车算法求最长回文子串)


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

    时间限制:C/C++ 2秒,其他语言4秒
    空间限制:C/C++ 262144K,其他语言524288K
    64bit IO Format: %lld

    题目描述

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

    输入描述:

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

    输出描述:

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

    输入

    复制
    dcbaabc

    输出

    复制
    7

    说明

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

    备注:

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


    解题思路:马拉车算法学习博客:https://www.cnblogs.com/grandyang/p/4475985.html
    枚举每一种情况,跑一遍马拉车算法即可。
    代码:
    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<vector>
    #include<string>
    #include<set>
    #include<cmath>
    #include<list>
    #include<deque>
    #include<cstdlib>
    #include<bitset>
    #include<stack>
    #include<map>
    #include<cstdio>
    #include<queue>
    using namespace std;
    typedef long long ll;
    #define lson l,mid,rt<<1
    #define rson mid+1,r,rt<<1|1
    #define pushup() tree[rt]=tree[rt<<1]+tree[rt<<1|1]
    const int INF=0x3f3f3f3f;
    const double PI=acos(-1.0);
    const double eps=1e-6;
    const ll mod=1e9+7;
    const int maxn=1000005;
    ll gcd(ll a,ll b){return b?gcd(b,a%b):a;}
    ll lcm(ll a,ll b){return a/gcd(a,b)*b;}
    const int dir[4][2]={{1,0},{-1,0},{0,1},{0,-1}};
    const int MAXN=2e6+10;
    int n,m,ans,p[MAXN];
    string st;
    int Manacher(string s,int st){
        string t="$#";
        for(int i=st,j=0;j<n;i++,j++){
            t+=s[i];
            t+='#';
        }
        //memset(p,0,sizeof(p));
        int mx=0,id=0,reslen=0,rescenter=0;
        for(int i=1;i<t.length();i++){
            p[i]=mx>i?min(p[2*id-i],mx-i):1;
            while(t[i-p[i]]==t[i+p[i]])p[i]++;
            if(mx<i+p[i]){
                mx=i+p[i];
                id=i;
            }
            if(reslen<p[i]){
                reslen=p[i];
                rescenter=i;
            }
        }
        return reslen-1;
        //return s.substr((reslen-rescenter)/2,reslen-1);
    }
    int main(){
        cin>>st;
        n=st.length();
        st=st+st;
        for(int i=0;i<n;i++){
            ans=max(ans,Manacher(st,i));
        }
        cout<<ans<<endl;
        return 0;
    }
  • 相关阅读:
    C语言指针入门
    c的动态内存管理
    汇编入门基础与helloworld
    汇编1
    汇编2——完整的例子集合
    算法与数据结构——选择,插入,希尔排序
    MySQL
    MySQL 笔记
    CSS样式优先级
    GIT使用笔记
  • 原文地址:https://www.cnblogs.com/zjl192628928/p/10770483.html
Copyright © 2020-2023  润新知