2022 Niuke winter vacation algorithm basic training camp

Posted by lobo235 on Sat, 29 Jan 2022 13:04:47 +0100


Title Link

preface

I cooked a chicken and wrote that I went to eat halfway (I can't write the questions after I don't eat...), and I will make up the questions later
Attached Official explanation

A zhinai's Hello XXXX

Problem solution

Nothing to say, direct output

code

print("hello ")

B zhinai buys melons

Problem solution / idea

Algorithm used: simple dp, similar to 01 knapsack (similar to the first scene).
Definition status: f(i,j) represents the number of schemes with the composition weight of j of the first i melons
State transition equation

f(i,j)=f(i-1,j)+f(i-1,j-a[i]/2)+f(i,j-a[i])

code

#include <bits/stdc++.h>
using namespace std;
#define int long long
const int N=1e3+10;
const int p=1e9+7;
int a[N],dp[N][N];
signed main()
{
    int n,m;
    cin>>n>>m;
    for(int i=1;i<=n;i++)
        cin>>a[i];
    dp[0][0]=1;
    for(int i=1;i<=n;i++)
    {
        for(int j=0;j<=m;j++)
        {
            if(j>=a[i])
                dp[i][j]=(dp[i-1][j-a[i]]+dp[i-1][j-a[i]/2]+dp[i-1][j])%p;
            else if(j>=a[i]/2)
                dp[i][j]=(dp[i-1][j-a[i]/2]+dp[i-1][j])%p;
            else
                dp[i][j]=dp[i-1][j];
        }
    }
    for(int i=1;i<=m;i++)
        cout<<dp[n][i]<<" ";
    return 0;
}

(scrolling array optimization)

#include <bits/stdc++.h>
using namespace std;
#define int long long
const int N=1e3+10;
const int p=1e9+7;
int a[N],dp[N];
signed main()
{
    int n,m;
    cin>>n>>m;
    for(int i=1;i<=n;i++)
        cin>>a[i];
    dp[0]=1;
    for(int i=1;i<=n;i++)
    {
        for(int j=m;j>=a[i]/2;j--)
        {
            //dp[j]=(dp[j-a[i]]+dp[j-a[i]/2]+dp[j])%p;
            if(j>=a[i])
                dp[j]=(dp[j-a[i]]+dp[j-a[i]/2]+dp[j])%p;
            else if(j>=a[i]/2)
                dp[j]=(dp[j-a[i]/2]+dp[j])%p;
        }
    }
    for(int i=1;i<=m;i++)
        cout<<dp[i]<<" ";
    return 0;
}

D zhinai's 01 string disturbance

Problem solution / idea

Just find the exchange location of the first 0 and the first 1 directly

code

#include <bits/stdc++.h>
using namespace std;
#define int long long
signed main()
{
    int n;
    string s;
    cin>>n>>s;
    int x,y;
    for(int i=0;i<n;i++)
    {
        if(s[i]=='0'){x=i;break;}
    }
    for(int i=0;i<n;i++)
    {
        if(s[i]=='1'){y=i;break;}
    }
    swap(s[x],s[y]);
    cout<<s<<endl;
    return 0;
}

E zhinai's digital building block (easy version)

Problem solution / idea

Simple questions, direct segmentation sorting, find blocks of the same color, and then sort
Because segments do not intersect, the complexity of each sorting is O(nlog n)
Another point is the idea of taking modulus of large numbers:
Let x = ABCD (the numbers in thousands, hundreds, tens, respectively)
x%p=a1000%p+b100%p+c10%p+d%p
=(((((a%p)10+b)%p10+c)%p*10)+d)%10

code

#include <bits/stdc++.h>
using namespace std;
#define int long long
const int N=1e5+10;
int col[N];
char s[N];
const int p=1e9+7;
int MOD(string str)
{
    int len=str.length();
    int s=0;
    for(int i=0; i<len; i++)
    {
        s=s*10+str[i]-'0';
        s=s%p;
    }
    return s;
}
bool cmp(char a,char b)
{
    return a>b;
}
signed main()
{
    int n,m,k;
    cin>>n>>m>>k;
    cin>>s;
    for(int i=0;i<n;i++)
        cin>>col[i];
    for(int i=0;i<n;i++)
    {
        int j=i+1;
        while(col[j]==col[i])
        {
            j++;
            if(j==n){break;}
        }
        //cout<<i<<" "<<j<<endl;
        sort(s+i,s+j,cmp);
        i=j-1;
    }
    cout<<MOD(s)<<endl;
    while(k--)
    {
        int p,q;
        cin>>p>>q;
        for(int i=0;i<n;i++)
            if(col[i]==p)col[i]=q;
        for(int i=0;i<n;i++)
        {
            int j=i+1;
            while(col[j]==col[i])
            {
                j++;
                if(j==n){break;}
            }
            sort(s+i,s+j,cmp);
            i=j-1;
        }
        cout<<MOD(s)<<endl;
    }
    return 0;
}

G zhinai's tree rotation (easy version)

Problem solution / idea

Look at the question, look at the question, there is an answer in the question (I understand it after reading it n times fw)
If you understand, you will find
When two nodes of two trees are in parent-child relationship with each other, the parent node can be output

code

#include<bits/stdc++.h>
using namespace std;
#define int long long
const int N=1e3+10;
struct tree
{
    int fa;
    int l,r;
}t1[N],t2[N];
signed main()
{
    int n;
    cin>>n;
    for(int i=1;i<=n;i++)
    {
        int l,r;
        cin>>l>>r;
        t1[i].l=l;
        t1[i],r=r;
        t1[l].fa=i;
        t1[r].fa=i;
    }
    for(int i=1;i<=n;i++)
    {
        int l,r;
        cin>>l>>r;
        t2[i].l=l;
        t2[i],r=r;
        t2[l].fa=i;
        t2[r].fa=i;
    }
    for(int i=1;i<=n;++i)
    {
        for(int j=1;j<=n;++j)
        {
            if(t1[i].fa==j&&t2[j].fa==i)
            {
                cout<<"1"<<endl;
                cout<<j<<endl;
                return 0;
            }
        }
    }
    cout<<0<<endl;
    return 0;
}

I zhinai's password

Problem solution / idea

The problem requires us to find three types of strings with length ∈ [L,R]
Let f(x) be the corresponding f(x) at each x position, the interval [x,f(x)] meets the requirements of the topic, and the interval [x,f(x)-1] does not meet the requirements (that is, the minimum J satisfying the condition corresponding to each i)
It can be found that for every J > I, there is f (J) > = f (I), which is monotonic
That's the idea. Two points~~~~
Of course, the method of double pointer (ruler) is simpler
But I always want to write two points (feel more high-end, more bug s...)
The idea of ruler sum is to find f(x) corresponding to each x position, and then calculate the number of schemes

code

#include <bits/stdc++.h>
using namespace std;
#define int long long
const int N=1e5+10;
char s[N];
int a[N],b[N],c[N],d[N];
bool check(int l,int r)
{
    int x=a[r]-a[l-1],y=b[r]-b[l-1],z=c[r]-c[l-1],p=d[r]-d[l-1];
    if((x>=1&&y>=1&&z>=1)||(x>=1&&y>=1&&p>=1)||(y>=1&&z>=1&&p>=1)||(x>=1&&p>=1&&z>=1))
        return 1;
    return 0;
}
signed main()
{
    int n,L,R;
    cin>>n>>L>>R>>s+1;
    for(int i=1;i<=n;i++)
    {
        a[i]=a[i-1];
        b[i]=b[i-1];
        c[i]=c[i-1];
        d[i]=d[i-1];
        if(s[i]>='A'&&s[i]<='Z')
            a[i]++;
        else if(s[i]>='a'&&s[i]<='z')
            b[i]++;
        else if(s[i]>='0'&&s[i]<='9')
            c[i]++;
        else 
            d[i]++;
        //cout<<a[i]<<" "<<b[i]<<' '<<c[i]<<' '<<d[i]<<endl;
    }
    int ans=0;
    for(int i=1;i<=n-L+1;i++)
    {
        int l=min(i+L-1,n),r=min(n,i+R-1);
        int y=r;
        while(l<r)
        {
            int mid=l+r>>1;
            if(check(i,mid))
                r=mid;
            else
                l=mid+1;
        }
        if(!check(i,l))continue;//Not satisfying the meaning of the question
        ans+=y-l+1;
    }
    cout<<ans<<endl;
    return 0;
}

L zhinai's database

Problem solution / idea

Because the data range of the topic is very small
So I directly handwritten sorting + de duplication (the code is ugly, I don't want to see it myself, so I suggest not to see it)

code

#include <bits/stdc++.h>
using namespace std;
#define int long long
const int N=1e5+10;
string s[1010];
int a[1010][1010];
char sql[50010],len;
map<string,int> q;
bool vis[1010];
struct xx
{
    int a[1010],len;
}p[1010];
bool cmp(xx a,xx b)
{
    for(int i=0;i<a.len;i++)
    {
        if(a.a[i]==b.a[i])continue;
        return a.a[i]<b.a[i];
    }
    return 0;
}
bool xx(xx a,xx b)
{
    for(int i=0;i<a.len;i++)
    {
        if(a.a[i]!=b.a[i])return 0;
    }
    return 1;
}
signed main()
{
    int n,m;
    cin>>n>>m;
    for(int i=1;i<=m;i++)
    {
        cin>>s[i];
        q[s[i]]=i;
    }
    for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++)
            cin>>a[i][j];
    getchar();
    scanf("SELECT COUNT(*) FROM Table GROUP BY ");
    len=0;
    int o=0;
    while(cin>>sql[len])
    {
        if(sql[len]==',')
        {
            sql[len]='\0';
            string ss=sql;
            vis[q[ss]]=1;
            len=0;
            o++;
            continue;
        }
        if(sql[len]==';')
        {
            sql[len]='\0';
            string ss=sql;
            vis[q[ss]]=1;
            len=0;
            o++;
            break;
        }
        len++;
    }
    len=0;
    for(int i=1;i<=n;i++)
    {
        int len=0;
        for(int j=1;j<=m;j++)
        {
            if(vis[j])
            {
                p[i].a[len++]=a[i][j];
            }
        }
        p[i].len=o;
    }
    sort(p+1,p+n+1,cmp);
    int ans=1,x=1;
    for(int i=2;i<=n;i++)
    {
        if(!xx(p[i],p[i-1]))
        {
            ans++;
        }
    }
    cout<<ans<<endl;
    for(int i=2;i<=n;i++)
    {
        if(xx(p[i],p[i-1]))//equal
        {
            x++;
        }
        else
        {
            cout<<x<<" ";
            x=1;
        }
    }
    cout<<x<<endl;
    return 0;
}

Topics: C++ Algorithm Dynamic Programming