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

Posted tqr06

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[20191004机房测试] C++锦标赛相关的知识,希望对你有一定的参考价值。

有一个比赛已经有 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++锦标赛的主要内容,如果未能解决你的问题,请参考以下文章

机房测试3:C++锦标赛(贪心)

C++实现机房预约系统完整源码分享!

如何对IDC机房网络带宽进行测试

IDC机房线路质量测试方案

机房测试10.6

机房测试9.22