2017年“华信智原杯”安徽省大学生程序设计大赛C题-刷票

C. 刷票 

 
题目描述: 

    有一个选秀比赛,节目组按照观众的投票情况决定选手的去留。为了给旗下 艺人造势,A 公司收买了一批水军来刷票。已知现在有 n 名选手同台竞争,依次 编号 1..n,A 公司的艺人编号为 1。根据节目组的规定,每人只能投票一次,投 票需要在 n 个选手中选出 m 个,这 m 个人每人可以获得一票。A 公司通过秘密 渠道得知了在 A 公司的水军不参与的情况下最终的投票结果,那么 A 公司想要 知道,如果要让公司旗下的艺人获得第一名(不能并列),至少要出动多少名水 军呢?如果无解,输出"Impossible"(不含引号) 

 
输入描述: 

    第一行输入正整数 T,表示数据的组数。 对于每组数据,第一行为两个正整数 n, m(1<=m<=n<=100000)。 第二行行为 n 个空格隔开的整数。表示第 i 个选手的得票数,且有 1... |1 100000 ii n a     

 
输出描述: 

    对于每组数据,输出一行,格式为'Case t: x',t 为数据的组号,x 为题目要求 的结果。 

 
输入样例: 

2

3 2

2 3 3

4 2

1 2 3 4 

 
输出样例:

Case 1: 4

Case 2: 5 

 
样例解释: 

    对于第一组数据,投票过程如下: 

    2 3 3 => 3 4 3 => 4 5 3 => 5 5 4 => 6 5 5 

    因此至少需要 4 名水军。


分析:

待更新

思路一:

待更新

思路二:

二分(一开始没想到,有思路后代码还是比较好写的。比想象的快,能水过,但是要关闭同步)

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;

int n, m, a[MAXN];

bool isok(int x,const int *a) {
    int a0 = a[0] + x;
    LL num = (LL)x*(m-1); //可能爆int 
    for(int i = 1; i < n; ++i) {
        if(a[i] >= a0)
            return false;
        if(a[i] + x < a0)
            num -= x;
        else
            num -= (a0-1-a[i]);
    }
    if(num <= 0)
        return true;
    return false;
}

int main()  
{  
    int T;
    ios::sync_with_stdio(false);
    cin >> T;
    for(int t = 1; t <= T; ++t) {
        cin >> n >> m;
        int k = 0;
        for(int i = 0; i < n; ++i) {
            cin >> a[i];
            if(a[i] >= a[k])
                k = i;
        }
        if(k == 0)
            cout << "Case " << t << ": 0" << endl;
        else if(n == m)
            cout << "Case " << t << ": Impossible" << endl;
        else {
            int l = 0, r = 100000, mid;
            while(l < r) {
                mid = (l+r)/2;
                if(isok(mid, a)) {
                    r = mid;
                }
                else {
                    l = mid+1;
                } 
            }
            cout << "Case " << t << ": " << l << endl;
        }
    }
    return 0;
} 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值