D. Prefix-Suffix Palindrome (马拉车)

D1

Link to the original question
I was ever violent d1
were taken from both ends equal character, find different after the stop, and then look for the prefix and suffix of violence from stop to position the longest palindrome string
of code:

#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;
}

Where n is an odd and even treatment is the same, but was written separately, so the code seems a bit long. . .

D2

D1 with roughly the same ideas, but need manacher something about
the code:

#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;
}

Published 36 original articles · won praise 4 · Views 1379

Guess you like

Origin blog.csdn.net/qq_43781431/article/details/105009339