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
 
 
原文地址:https://www.cnblogs.com/qywyt/p/15228575.html