首页 > 编程语言 > 详细

[20191004机房测试] C++锦标赛

时间:2019-10-04 19:34:54      阅读:84      评论:0      收藏:0      [点我收藏+]
有一个比赛已经有 n 个人参加,并且互相之间已经进行了比赛
每一个人都有一个得分用于最后排名
你作为第 n + 1 个参赛者,需要与之前的每一个人打一场比赛,初始得分为 0
对于每场比赛,有两个人参加,不会存在平局,胜者得分增加 1,败者得分不变
最后按照得分从高到低来排名,假设有人与你最终得分相同
那么如果那个人曾经输给了你就会排在你后面,否则会排在你的前面
如果你赢了某个人,就需要消耗相应的 RP 值
现在你可以决定赢那些人,求最少需要消耗多少 RP 值才能到前k名

50分做法:还是枚举二进制串……居然有50分

100分做法:
这个满分做法是真的玄学,我们需要分三种情况讨论来贪心求解:

  1. 如果一个人的胜场和自己相同或者刚好少1,不打就会被挤下去,打了就可以升一位
  2. 如果一个人的胜场比自己多,打不打都没什么差异……
  3. 如果一个人的胜场比自己少2或者更多,那就可以不用打了
    然后贪心就好

代码:

#include<bits/stdc++.h>
#define ll long long
#define maxn 2505
using namespace std;

int T,n,k,gol,num;
ll ans;
bool used[maxn];

struct People
{
    int p, e;
}p[maxn];

bool cmp1(People x, People y) {return x.p > y.p;}
bool cmp2(People x, People y) {return x.e < y.e;}

bool check()
{
    int res=0;
    for(register int i=1;i<=n;++i)
        if(p[i].p>n) res++;
    return res>=k;
}

ll work1()
{
    ll ret=0;   
    int cnt=gol,num1=0,num2=num;
    for(register int i=1;i<=n;++i)
    {
        used[i]=0;
        if(p[i].p==gol-1) ++num1; 
    }
    for(register int i=1;i<=n&&num2;++i)
    {
        if(p[i].p==gol)
        {
            ret=ret+p[i].e; 
            used[i]=1;
            --cnt;
            --num2;
        }
    }
    for(register int i=1;i<=n&&num1;++i)
    {
        if(!used[i]&&(p[i].p==gol||p[i].p==gol-1))
        {
            ret=ret+p[i].e; 
            used[i]=1;
            --cnt;
            --num1;
        }
    }
    for(register int i=1;i<=n&&cnt;++i)
    {
        if(!used[i])
        {
            ret=ret+p[i].e;
            --cnt;
        }
    }
    return ret;
}

ll work2()
{
    ll ret=0;
    int num2=num,cnt=gol+1;
    for(register int i=1;i<=n;++i) used[i]=0;
    for(register int i=1;i<=n&&num2;++i)
    {
        if(p[i].p==gol||p[i].p==gol+1)
        {
            used[i]=1;
            ret=ret+p[i].e;
            --cnt;
            --num2;
        }
    }
    for(register int i=1;i<=n&&cnt;++i)
    {
        if(!used[i])
        {
            ret=ret+p[i].e;
            --cnt;
        }
    }
    return ret;
}

ll work3()
{
    ll ret=0;
    for(register int i=1;i<=gol+2;++i)
        ret=ret+p[i].e;
    return ret;
}

template<class T>inline void read(T &res)
{
    char c;T flag=1;
    while((c=getchar())<'0'||c>'9')if(c=='-')flag=-1;res=c-'0';
    while((c=getchar())>='0'&&c<='9')res=res*10+c-'0';res*=flag;
}

int main()
{
    freopen("tournament.in","r",stdin);
    freopen("tournament.out","w",stdout);
    read(T);
    while(T--)
    {
        read(n);read(k);
        for(register int i=1;i<=n;++i) scanf("%d%d",&p[i].p,&p[i].e);
        if(k==n+1)
        {
            printf("0\n");
            continue;
        }
        if(check())
        {
            printf("-1\n");
            continue;
        }
        sort(p+1,p+n+1,cmp1);
        gol=p[k].p;
        num=1;
        while(p[k+num].p==p[k].p&&k+num<=n) ++num;
        sort(p+1,p+n+1,cmp2);
        ans=min(work1(),min(work2(),work3()));
        printf("%lld\n",ans);
    }
    return 0;
}

[20191004机房测试] C++锦标赛

原文:https://www.cnblogs.com/tqr06/p/11622889.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!