D. Prefix-Suffix Palindrome (马拉车)

D1

原题链接
当时我是暴力过的d1
分别从两端取相等的字符,找到不同的后停下来,再从停下来的位置暴力查找前缀和后缀的最长回文串
代码:

#include <bits/stdc++.h>
#define ll long long
using namespace std;
string a,s;
int query(int a,int b)
{
    int nn=b-a+1;
    if(nn%2==0)
    {
        int flag=1;
        for(int i=0;i<nn/2;i++)
        {
            if(s[a+i]!=s[b-i])
            {flag=0;break;}
        }
        return flag;
    }
    if(nn%2!=0)
    {
        int flag=1;
        for(int i=0;i<nn/2+1;i++)
        {
            if(s[a+i]!=s[b-i])
            {flag=0;break;}
        }
        return flag;
    }
}
int main()
{
    int t;
    cin>>t;
    while(t--)
    {
        cin>>s;
        int n=s.size();
        if(n%2==0)
        {
            int ii=0,jj=0;
            for(int i=0;i<n/2;i++)
            {
                if(s[i]==s[n-i-1])
                {continue;}
                if(s[i]!=s[n-i-1])
                {
                    ii=i;
                    jj=n-i-1;
                    break;
                }
            }
            if(ii==0&&jj==0)
            {cout<<s<<endl;
            continue;}
            int zz,hh,z,h;
            for(int i=jj;i>=ii;i--)
            {
                if(query(ii,i))
                {zz=i-ii+1;z=i;break;}
            }
            for(int i=ii;i<=jj;i++)
            {
                if(query(i,jj))
                {hh=jj-i+1;h=i;break;}
            }
            if(zz>=hh)
            {
                for(int i=0;i<=z;i++)
                {cout<<s[i];}
                for(int i=jj+1;i<n;i++)
                {cout<<s[i];}
                cout<<endl;
            }
            else
            {
                for(int i=0;i<ii;i++)
                {cout<<s[i];}
                for(int i=h;i<n;i++)
                {cout<<s[i];}
                cout<<endl;
            }
        }
        if(n%2!=0)
        {
            int ii=0,jj=0;
            for(int i=0;i<n/2;i++)
            {
                if(s[i]==s[n-i-1])
                {continue;}
                if(s[i]!=s[n-i-1])
                {
                    ii=i;
                    jj=n-i-1;
                    break;
                }
            }
            if(ii==0&&jj==0)
            {cout<<s<<endl;
            continue;}
            int zz,hh,z,h;
            for(int i=jj;i>=ii;i--)
            {
                if(query(ii,i))
                {zz=i-ii+1;z=i;break;}
            }
            for(int i=ii;i<=jj;i++)
            {
                if(query(i,jj))
                {hh=jj-i+1;h=i;break;}
            }
            if(zz>=hh)
            {
                for(int i=0;i<=z;i++)
                {cout<<s[i];}
                for(int i=jj+1;i<n;i++)
                {cout<<s[i];}
                cout<<endl;
            }
            else
            {
                for(int i=0;i<ii;i++)
                {cout<<s[i];}
                for(int i=h;i<n;i++)
                {cout<<s[i];}
                cout<<endl;
            }
        }
    }
    return 0;
}

这里n是奇数和偶数处理是一样的,只不过当时分开写了,所以显得代码有点长。。。

D2

跟D1思路大致相同,只不过需要manacher处理一下
代码:

#include <bits/stdc++.h>
#define ll long long
using namespace std;
int d[3000005],len;
void manacher(string s)
{
    int mx=0,p=0;
    for(int i=1;i<=len;i++)
    {
        if(mx>i)
            d[i]=min(mx-i,d[2*p-i]);
        else
            d[i]=1;
        while(s[i-d[i]]==s[i+d[i]])
        {d[i]++;}
        if(d[i]+i>mx)
        {
            mx=d[i]+i;
            p=i;
        }
    }
}
int main()
{
    int t;
    string c;
    cin>>t;
    while(t--)
    {
        cin>>c;
        len=0;
        int n=c.size();
        if(n==1){cout<<c<<endl;continue;}
        string s="";
        d[0]=0;
        s+="@";len++;
        for(int i=0;i<n;i++)
        {
            s+="#";len++;
            s+=c.substr(i,1);len++;
        }
        s+="#";
        for(int i=0;i<len+3;i++)
        {d[i]=0;}
        manacher(s);
        //////////////////////////////////////////
        int ii=0,jj=0;
        for(int i=1;i<=len;i++)
        {
            if(s[i]!=s[len-i+1])
            {ii=i;jj=len-i+1;break;}
        }
        if(ii==0&&jj==0){cout<<c<<endl;continue;}
        int zz=0,hh=0,z,h;
        for(int i=jj;i>=ii;i-=2)
        {
            int mid=(ii+i)/2;
            if((d[mid]+mid-1)>=i)
            {zz=i-ii+1;z=i;break;}
        }
        for(int i=ii;i<=jj;i+=2)
        {
            int mid=(i+jj)/2;
            if((mid-d[mid]+1)<=i)
            {hh=jj-i+1;h=i;break;}
        }
        if(zz>=hh)
        {
            for(int i=1;i<=z;i++)
            {if(s[i]!='#'){cout<<s[i];}}
            for(int i=jj+1;i<=len;i++)
            {if(s[i]!='#'){cout<<s[i];}}
            cout<<endl;
        }
        else
        {
            for(int i=1;i<ii;i++)
            {if(s[i]!='#'){cout<<s[i];}}
            for(int i=h;i<=len;i++)
            {if(s[i]!='#'){cout<<s[i];}}
            cout<<endl;
        }
    }
    return 0;
}

发布了36 篇原创文章 · 获赞 4 · 访问量 1379

猜你喜欢

转载自blog.csdn.net/qq_43781431/article/details/105009339