CodeForces - 773B 贪心 非二分

题目链接:http://codeforces.com/contest/773/problem/B

 

题意:

       给了你一个不知真假的cf的判题标准(该题基础分由通过人数和题交人数的比值决定,该题可得分数还要减去通过时间/250,保证通过时间<=119),然后一号用户想赢二号用户,造了1e9+7个小号(因为:假设某一题1号过得快,它可以通过让小号wa来增加这个题的基础分让自己多拿一点分,如果他过的慢,那么他就可以多让小号a掉让这个题的基础分减小让这题不值钱),然后问题来了,这里还有个条件,假设1号用户没过这个题,那么它的小号也交不了a,就是这个额外条件让这个题不能二分。

 

做法:

       小号的作用无疑是放大了分数,但是假设1号用户有一道a不了的题,但是这个题2号过的很快,那么如果1号用户有很多小号的话,这个题就默认有了很高的分数,这就对1号是不利的,这种时候就宁愿让人少一点,可能在减少这道题分数的情况下其他题也能凑到。

        比如样例

十七人

66 15 -1 42 90
67 108 104 16 110

其他人的题目总通过人数为12 9 12 13 11人

        如果二分,第一次的比值太大,1 2 3 5 的分值都是3000,4是500,但是这样无疑是放大了3号题,1号也过不了,那么还不如小一些,5个人让分数为500,1000,500,500,500,也就够了。

       因为比值在1/32之后就没有了,所以最大人数其实不用1e9+7,只要120*32大概40000也就够了


#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=100005;
ll n,yes[6];
ll peo[3][6];
ll gain(ll ac,ll all){
    if(ac*2>all) return 500;
    else if(ac*4>all) return 1000;
    else if(ac*8>all) return 1500;
    else if(ac*16>all) return 2000;
    else if(ac*32>all) return 2500;
    else return 3000;
}
ll Cal(ll bas,ll tim){
    return bas-tim*bas/250;
}
int ck(ll m){
    ll fi=0,se=0;
    for(int i=1;i<=5;i++){
        if(peo[1][i]==peo[2][i]) continue;
        if(peo[1][i]<peo[2][i]){
            fi=fi+Cal(gain(yes[i],n+m),peo[1][i]);
            se=se+Cal(gain(yes[i],n+m),peo[2][i]);
            //printf("pro=%d so=%d\n",i,gain(yes[i],n+m));
        }
        else{
            if(peo[1][i]==250){
                fi=fi+Cal(gain(yes[i],n+m),peo[1][i]);
                se=se+Cal(gain(yes[i],n+m),peo[2][i]);
                //printf("pro=%d so=%d\n",i,gain(yes[i],n+m));
            }
            else{
                fi=fi+Cal(gain(yes[i]+m,n+m),peo[1][i]);
                se=se+Cal(gain(yes[i]+m,n+m),peo[2][i]);
                //printf("pro=%d so=%d\n",i,gain(yes[i]+m,n+m));
            }
        }
    }

    return fi>se;
}
int main(){
    scanf("%lld",&n);
    int tmp=n;
    for(int i=1;i<=n;i++){
        int f=0;
        for(int j=1;j<=5;j++){
            int x;
            scanf("%d",&x);
            if(x!=-1) yes[j]++,f=1;
            if(i<=2){
                if(x==-1) x=250;
                peo[i][j]=(ll)x;
            }
        }
        if(f==0)tmp--;
    }
    n=tmp;
    for(int i=0;i<=50000;i++){
        if(ck(i)){
            printf("%d\n",i);
            return 0;
        }
    }
    printf("-1\n");
    return 0;
}
/*
2
66 15 -1 42 90
67 108 104 16 110

*/

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值