zoukankan      html  css  js  c++  java
  • Prefix-Suffix Palindrome (Hard version) (补) (Manacher)

    题目:

    给你一个字符串,让你找一个最大回文串,这个回文串由该字符串的前缀和后缀一起组成

    思路:

    先处理字符串的两端直到两端不匹配为止,然后对中间的字符串跑一遍Manacher算法,然后

    找出起始点为1或终止点为s.size()的最大回文串输出(这样才能保证满足前缀或后缀的条件),再分别输出即可

    链接:

    https://codeforces.com/contest/1326/problem/D2

    代码:

    #include <bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const int MAXN=2e6+5;
    const int INF=0x3f3f3f3f3f3f3f;
    const int mod=998244353;
    string s,s1;
    int len[MAXN];
    void init(int l,int r)
    {
        s+='$';s+='#';
        for(int i=l;i<=r;i++)
        {
            s+=s1[i];
            s+='#';
        }
    }
    int start,max_r;    //start表示起始点,max_r表示回文串的最长半径
    void manacher()
    {
        int mx=0,id=0;
        for(int i=1;i<s.size();i++)
        {
            len[i]=mx>i?min(len[2*id-i],mx-i):1;
            while(s[i+len[i]]==s[i-len[i]])
                len[i]++;
            if(i+len[i]>mx)
            {
                mx=i+len[i];id=i;
            }
            if(i==len[i])
            {
                if(max_r<len[i])
                    start=1,max_r=len[i];
            }
            else
                if(i+len[i]==s.size())
            {
                if(max_r<len[i])
                    start=i-len[i]+1,max_r=len[i];
            }
        }
    }
    int main()
    {
        ios::sync_with_stdio(false);cin.tie(0);
        int t;cin>>t;
        while(t--)
        {
            s="",start=0,max_r=0;
            cin>>s1;
            int len=s1.size();
            int l=0,r=len-1;
            while(s1[l]==s1[r])
                r--,l++;
            //cout<<l<<" "<<r<<endl;
            if(l>r)
                cout<<s1<<endl;
            else
            {
                init(l,r);
                for(int i=0;i<l;i++)
                    cout<<s1[i];
                manacher();
                for(int i=start;i<=start+(max_r-1)*2;i++)
                {
                    if(s[i]=='#')
                    continue;
                    cout<<s[i];
                }
                for(int i=r+1;i<s1.size();i++)
                    cout<<s1[i];
                cout<<endl;
            }
    
        }
    }
  • 相关阅读:
    关于ADO.NET参数化查询的提问
    PushSharp的使用
    关于WCF的一些知识点
    关于Expression表达式树的拼接
    设计模式-策略模式
    jq图片展示插件highslide.js简单dom
    JS实现手机访问pc网址自动跳转到wap网站
    CARVARS 圆形进度条
    vue-router的几种用法
    vscode 超好用的前端插件
  • 原文地址:https://www.cnblogs.com/ljxdtc666/p/12554537.html
Copyright © 2011-2022 走看看