• Educational Codeforces Round 18


    来自FallDream的博客,未经允许,请勿转载,谢谢。

    ---------------------------------------------------------------------

    A.New Bus Route

    给定n个数,求最小的任意两个数的差的绝对值和最小值个数。$nleqslant 2*10^{5}$

    题解:排序完暴力。

    #include<iostream>
    #include<cstdio>
    #include<cmath>
    #include<queue>
    #include<cstring>
    #include<queue>
    #include<algorithm>
    #define ll long long
    #define INF 2000000000
    using namespace std;
    inline int read()
    {
        int x=0,f=1;char ch=getchar();
        while(ch<'0'||ch>'9'){if(ch=='-') f=-1;ch=getchar();}
        while(ch>='0'&&ch<='9'){x=x*10+ch-'0'; ch=getchar();}
        return x*f;
    }
    
    int n,minn=INF,num=0;
    int s[200005];
    int main()
    {
        n=read();
        for(int i=1;i<=n;i++)s[i]=read();
        sort(s+1,s+n+1);
        for(int i=2;i<=n;i++)
        {
            int x=s[i]-s[i-1];
            if(x<minn){minn=x;num=1;}
            else if(x==minn)num++;
        }
        cout<<minn<<endl<<num;
        return 0;
    }

    B.Counting-out Rhyme

    n个人围成环,每个人有一个数字,一开始从第一个人开始,数它的数字那么多个人,然后那个人离开,从它的下一个人继续...总共玩了k轮,你要输出离开的人的顺序。n,k<=100

    题解:直接暴力就好了。

    #include<iostream>
    #include<cstdio>
    #include<cmath>
    #include<queue>
    #include<cstring>
    #include<queue>
    #include<algorithm>
    #define ll long long
    #define INF 2000000000
    using namespace std;
    inline int read()
    {
        int x=0,f=1;char ch=getchar();
        while(ch<'0'||ch>'9'){if(ch=='-') f=-1;ch=getchar();}
        while(ch>='0'&&ch<='9'){x=x*10+ch-'0'; ch=getchar();}
        return x*f;
    }
    int n,k,pos=1;
    int nx[105],la[105];
    
    void del(int x)
    {
        la[nx[x]]=la[x];
        nx[la[x]]=nx[x];
    }
    
    int main()
    {
        n=read();k=read();
        for(int i=1;i<n;i++)la[i+1]=i,nx[i]=i+1;
        la[1]=n;nx[n]=1;
        for(int i=1;i<=k;i++)
        {
            int a=read()%n;
            for(int j=1;j<=a;j++)
                pos=nx[pos];
            printf("%d
    ",pos);
            pos=nx[pos];del(la[pos]);--n;
        }
        return 0;
    }

    C. Divide by Three

    给定一个十进制数n,你要删去最少的位数使得剩下的数没有前导0且能被3整除。   $nleqslant10^{100000}$

    题解:可以从后往前贪心。但是我菜,所以我只会写dp

    #include<iostream>
    #include<cstdio>
    #include<cmath>
    #include<queue>
    #include<cstring>
    #include<queue>
    #include<algorithm>
    #define ll long long
    #define INF 1000000000
    #define MN 100000000
    using namespace std;
    inline int read()
    {
        int x=0,f=1;char ch=getchar();
        while(ch<'0'||ch>'9'){if(ch=='-') f=-1;ch=getchar();}
        while(ch>='0'&&ch<='9'){x=x*10+ch-'0'; ch=getchar();}
        return x*f;
    }
    
    int s[100005];
    int from1[100005][5],from2[100005][5];
    int f1[100005][5],n,f2[100005][5];
    char st[100005];
    
    int main()
    {
        scanf("%s",st+1);n=strlen(st+1);
        for(int i=1;i<=n;i++)
            s[i]=(st[i]-'0')%3;
        memset(f1,127,sizeof(f1));memset(f2,127,sizeof(f2));
        for(int i=n;i;i--)
        {
            f1[i][s[i]]=n-i;
            for(int j=0;j<=2;j++)
            {
                int nx=(j+3-s[i])%3;
                if(f1[i+1][nx]<=f1[i][j]){f1[i][j]=f1[i+1][nx];from1[i][j]=MN+(i+1)*10+nx;}
                if(f2[i+1][nx]<=f1[i][j]){f1[i][j]=f2[i+1][nx];from1[i][j]=(i+1)*10+nx;}
                if(f1[i+1][j]+1<=f2[i][j]){f2[i][j]=f1[i+1][j]+1;from2[i][j]=MN+(i+1)*10+j;}
                if(f2[i+1][j]+1<=f2[i][j]){f2[i][j]=f2[i+1][j]+1;from2[i][j]=(i+1)*10+j;}
            }
        }
        int ans=INF;int ansfrom;
        for(int i=1;i<=n;i++)if(st[i]!='0')
            if(f1[i][0]+i-1<ans){ans=f1[i][0];ansfrom=MN+i*10;}for(int i=1;i<=n;i++)if(st[i]=='0')
        {
            if(n-1<ans)return 0*puts("0");
            break;
        }
        if(ans>=INF) return 0*puts("-1");
        for(int i=ansfrom;i;)
        {
            if(i>=MN)cout<<st[i%MN/10],i=from1[i%MN/10][i%10];
            else i=from2[i/10][i%10];
        }
        return 0;
    }

    D.给定一个特殊编号方法的完全二叉树,然后给定初始位置和每次移动的方向,求最后在哪一个位置。

    题解:直接找规律或者模拟一下线段树都可以。

    #include<iostream>
    #include<cstdio>
    #include<cmath>
    #include<queue>
    #include<cstring>
    #include<queue>
    #include<algorithm>
    #define ll long long
    #define INF 1000000000
    #define MN 100000000
    using namespace std;
    inline ll read()
    {
        ll x=0,f=1;char ch=getchar();
        while(ch<'0'||ch>'9'){if(ch=='-') f=-1;ch=getchar();}
        while(ch>='0'&&ch<='9'){x=x*10+ch-'0'; ch=getchar();}
        return x*f;
    }
    
    ll n;int q,d=0,dep;
    char s[100005];
    
    ll pd(ll x)
    {
        x+=(1LL<<(d-dep));
        x/=(1LL<<(d-dep+1));
        return (x&1LL)?-1:1;
    }
    
    int main()
    {
        n=read();q=read();
        for(ll i=n;i;i>>=1)d++;
        for(int i=1;i<=q;i++)
        {
            ll x=read();scanf("%s",s+1);dep=d;
            for(ll i=x;!(i&1);i>>=1) --dep;
            for(int i=1;s[i];i++)
            {
                if((s[i]=='L'||s[i]=='R')&&dep==d)continue;
                if(s[i]=='U'&&dep==1)continue;
                if(s[i]=='L')x-=(1LL<<(d-dep-1));
                if(s[i]=='R')x+=(1LL<<(d-dep-1));
                if(s[i]=='U')x-=pd(x)*(1LL<<(d-dep));
                dep+=(s[i]!='U')?1:-1;
            }
            printf("%lld
    ",x);
        }
    }

    E.Colored Balls

    给n堆球,可以把每一堆分成多堆,但是要求任意两个分成的堆的个数相差不超过1.   $nleqslant 500 bi    leqslant 10^{9}$

    题解:考虑最小的堆分成多大,这个只有根号种可能,然后每次check一下,复杂度$nsqrt max)$

    #include<iostream>
    #include<cstdio>
    #include<cmath>
    #include<queue>
    #include<cstring>
    #include<queue>
    #include<algorithm>
    #define ll long long
    #define INF 100000000000000LL
    #define ll long long
    #define MN 100000000
    using namespace std;
    inline int read()
    {
        int x=0,f=1;char ch=getchar();
        while(ch<'0'||ch>'9'){if(ch=='-') f=-1;ch=getchar();}
        while(ch>='0'&&ch<='9'){x=x*10+ch-'0'; ch=getchar();}
        return x*f;
    }
    
    int n,s[1005];
    ll ans=INF,size;ll mn=INF;
    
    void calc(int x)
    {
        if(!x) return ;size=0;
        for(int i=1;i<=n;i++)
        {
            int mod=s[i]%x,div=s[i]/x;
            if(mod>div)return;
            size+=(s[i]+x)/(x+1);
        }
        ans=min(ans,size);
    }
    
    int main()
    {
        n=read();
        for(int i=1;i<=n;i++)s[i]=read(),mn=min(mn,(ll)s[i]);
        for(int i=1,last;i<=mn;i=last+1)
        {
            last=mn/(mn/i);int ques=mn/i;
            calc(ques);calc(ques-1);
            //calc(ques+1);
        }
        cout<<ans;
        return 0;
    }
  • 相关阅读:
    You Will Be Memorizing Things
    PowerShell与cmd
    select的一些问题。
    深刻理解数据库外键含义
    html居中问题
    jsp中嵌入的html
    jdbc连接mysql报错:com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Unknown column '金厉旭' in 'field list'
    [kuangbin带你飞]专题一 简单搜索
    算法竞赛训练指南11.2 最小生成树
    [kuangbin带你飞]专题六 最小生成树
  • 原文地址:https://www.cnblogs.com/FallDream/p/codeforecesEdu18.html
Copyright © 2020-2023  润新知