NBU:1651 Red packet(二分)【好】

  • [1651] Red packet

  • 时间限制: 1000 ms 内存限制: 65535 K
  • 问题描述
  • New Year is coming! Our big boss Wine93 will distribute some “Red Package”, just like Alipay and Wechat.

    Wine93 has m yuan, he decides to distribute them to n people and everyone can get some money(0 yuan is not allowed and everyone’s money is an integer), Now k people has gotten money, it’s your turn to get “Red Package”, you want to know, at least how much money to give you, then you can must become the “lucky man”. and the m yuan must be used out.

    Noting that if someone’s money is strictly much than others’, than he is “lucky man”.


  • 输入
  • Input starts with an integer T (T <= 50) denoting the number of test case.
    For each test case, three integers n, m, k (1 <= k < n <= 100000, 0< m <= 100000000) will be given.
    Next line contains k integers, denoting the money that k people get. You can assume that the k integers’ summation is no more than m.
  • 输出
  • Ouput the least money that you need to become the “lucky man”, if it is impossible, output “Impossible” (no quote).
  • 样例输入
  • 3
    3 5 2
    2 1
    4 10 2
    2 3
    4 15 2
    3 5
    
  • 样例输出
  • Impossible
    4
    6
    
  • 提示
题目大意:老板给n个人发红包,老板共发m元,给出了k个已发员工的钱数信息,问如果你想当lucky one(运气汪?)的话,最少你得得到多少钱的红包。(lucky one,就是你在所有人中收到的红包严格最大)
解题思路:分情况。不可能的情况:就是给剩下的人一人发一块,而我却拥有剩下的所有钱,但是却没有已经发红包的人的最大值大,不能成为lucky one。排除了不可能的情况,接下来就是可能的情况了:二分上下限控制好,代码中注释已经详细解释了。
代码如下:
#include <cstdio>
#include <algorithm>
using namespace std;
int n,m,k;
int sheng,sum,maxx;
bool judge(int x)
{
	if((m-sum-(n-k-2)-x)<x)//如果除了我,从剩下的没发钱的人中挑一个,然后剩下的剩下的人一人一块,那么所挑出来的这个人所拥有的钱数在这些人里面最多,但是没有我x多的话。。 
	return true;
	else
	return false;
}
int main()
{
	int t;
	scanf("%d",&t);
	while(t--)
	{
		maxx=0;//标记已发钱的人中最有钱的人有多少钱 
		sum=0;//发钱的总数 
		int z;//中间变量 
		scanf("%d%d%d",&n,&m,&k);
		for(int i=0;i<k;i++)
		{
			scanf("%d",&z);
			sum=sum+z;
			maxx=max(maxx,z);
		}
		//下面的m-sum即是剩下的没发的钱 
		int l=maxx+1;//如果可能是lucky one的话,则左区间一定比maxx大一开始扫 
		int r=m-sum-(n-k-1);//右区间是除了我以外,剩下的没发钱的人一人发一块 
		if((m-sum-(n-k-1))<=maxx)//除了已发钱的人和我本人,剩下的人都一人发一块,但是剩下的钱(归我)也没maxx大,所以不可能是lucky one。 
		{
			printf("Impossible\n");
			continue;
		}
		int mid;
		while(l<=r)
		{
			mid=(l+r)/2;
			if(judge(mid))
			{
				r=mid-1;
			}
			else
			{
				l=mid+1;
			}
		}
		printf("%d\n",l);//why??输出mid就wa,没道理。。。 
	}
	return 0;
}



评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值