• 2019-2020 ACM-ICPC Brazil Subregional Programming Contest


      B - Buffoon

      读入n和vi,如果有vi大于v1输出N,v1大于等于其他vi输出S。

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll ;
    int read(){    int x;scanf("%d",&x);return x;}
    int n,a;
    int main()
    {
        n=read();
        a=read();
        for(n--;n;n--)
        {
            if(read()>a)
            {
                cout<<'N';
                return 0;
            }
        }
        cout<<'S'; 
    }
    View Code

      H - Hour for a Run

      一个人跑圈,一共v圈每圈n个记号,问分别看到哪个记号可以得知跑过了10%、20%、30%...通过大胆猜测比对样例可以知道是输出v*n*10%、v*n*20%...向上取整。

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll ;
    int read(){    int x;scanf("%d",&x);return x;}
    int v,n;
    int main()
    {
        cin>>v>>n;
        for(int i=1;i<=9;i++)
        {
            int t=ceil(v*n*i*0.1);
            cout<<t<<' ';
        }
    }
    View Code

      M - Maratona Brasileira de Popcorn

      n包爆米花,c个人一起吃,每个人每秒最多可以吃T个,每个人吃的爆米花需要是连续的几包不能有某一包有好多人吃过。问需要的最短时间。

      经典二分答案扫一遍。我刚开始以为每天只能吃同一包里的,但其实不是,可以吃完这包吃下一包,总数小于T即可。

      记得开ll。

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll ;
    ll read(){    ll x;scanf("%lld",&x);return x;}
    ll n,c,t,l,r,mid,a[100010];
    bool check(ll x)
    {
        
        ll sum=1,now=x;
        for(int i=1;i<=n;i++)
        {
            if(now>=a[i])
                now-=a[i];
            else
            {
                sum++;
                now=x-a[i];
            }
        }
        return sum<=c;
    }
    int main()
    {
        n=read();c=read();t=read();
        for(int i=1;i<=n;i++)
        {
            a[i]=read();
            r+=a[i];
            l=max(l,a[i]);
        }
        r=(r+t-1)/t;
        l=(l+t-1)/t;
        while(l+1<r)
        {
            mid=(l+r)/2;
            if(check(mid*t))
                r=mid;
            else
                l=mid;
        }
        if(check(l*t))
            cout<<l;
        else
            cout<<r;
    }
    View Code

       J - Jar of Water Game

      n个人,从k开始轮流转圈给牌,k刚开始手上有一个wildcard。当前操作的人是k、k+1、k+2、...n、1、2...以此类推,当前操作的人如果没有wildcard或者有wildcard且刚拿到wildcard,那么选出手里出现次数最小且牌数字最小的牌给下一个人;如果有wildcard且不是刚拿到,那么把wildcard给下一个人。当场上有人手上只有四张牌且牌面相等时牌面最小的人就赢了。

      所以每送普通牌送一圈后才有一次wildcard的移动。感觉这个题意属实令人摸不着头脑。

      每个人有的牌不一定一样所以用c[i][j]记录第i个人有几张j牌。用k表示wildcard在谁哪里,flag=0表示是刚拿到,flag=1表示不是刚拿到。

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    int read(){int x;scanf("%d",&x);return x;}
    int n,k,b[20],c[20][20];
    string s;
    struct node
    {
        int i,x;
        friend bool operator <(node a,node b)
        {
            return a.x>b.x;
        }
    };
    priority_queue<node>o;
    void work()
    {
        for(int i=1;i<=n;i++)
        {
            if(i==k)continue;
            int sum=0;
            for(int j=1;j<=13;j++)
                sum+=c[i][j];
            if(sum!=4)
                continue;
            for(int j=1;j<=13;j++)
                if(c[i][j]==4&&i!=k)
                    o.push(node{i,j});
        }
        if(o.size())
        {
            cout<<o.top().i;
            exit(0);
        }
    }
    int now;
    int main()
    {
        n=read();now=k=read();
        for(int i=1;i<=n;i++)
        {
            cin>>s;
            for(int j=0,k=1;j<4;j++,k++)
            {
                if(s[j]=='A')
                    c[i][1]++;
                else if(s[j]=='D')
                    c[i][10]++;
                else if(s[j]=='Q')
                    c[i][11]++;
                else if(s[j]=='J')
                    c[i][12]++;
                else if(s[j]=='K')
                    c[i][13]++;
                else
                    c[i][s[j]-'0']++;
            }
        }
        work();
        int flag=0;
        while(1)
        {
            work();
            b[now]=0;
            for(int j=1;j<=13;j++)
            {
                if(c[now][j]!=0&&(b[now]==0||c[now][j]<c[now][b[now]]))
                    b[now]=j;
            }
            if(now==k)
            {
                if(flag==0)
                {
                    c[now][b[now]]--;
                    c[now%n+1][b[now]]++;
                    flag=1;
                }
                else
                {
                    k=k%n+1;
                    flag=0;
                }
            }
            else
            {
                c[now][b[now]]--;
                c[now%n+1][b[now]]++;
            } 
            work();
            now=now%n+1;
        }
    } 
    View Code
     
     
  • 相关阅读:
    [wikioi]最长严格上升子序列
    [leetcode]Pascal's Triangle II
    [leetcode]Remove Duplicates from Sorted Array II
    [leetcode]Remove Duplicates from Sorted List
    STL中set底层实现方式
    有N个大小不等的自然数(1--N),请将它们由小到大排序。要求程序算法:时间复杂度为O(n),空间复杂度为O(1)。
    C#基本语句
    C#程序大打开
    如何知道自己是工作组计算机中的哪个
    weka平台
  • 原文地址:https://www.cnblogs.com/qywyt/p/15228575.html
Copyright © 2020-2023  润新知