牛客NC15098 题解

题目描述
今天是某不愿透露姓名的谈姓大佬的生日,转发这场比赛到三个群就可以,获得以下三种礼包之一。
豪华礼包:一个U盘、一个鼠标和一个机械键盘。
幸运礼包:一个U盘、两个鼠标。
普通礼包:两个U盘、一个鼠标。
大佬一共准备了a个U盘、b个鼠标和c个机械键盘。为了给更多的人带来足够多的惊喜,大佬希望相邻的两位领礼包的参赛选手拿到的礼包类型都是不同的。
由于大佬正在宴请Final选手,并没有空打理这些,所以想让你告诉他 这些奖品最多可以发出多少份礼包。
输入描述:
输入第一行包含一个正整数T。
接下来T行每行包含3个正整数a, b, c,依次表示U盘、鼠标和机械键盘各有多少个。

输出描述:
输出T行,每行一个整数,表示最多能发出多少份礼包。
示例1
输入
2
4 4 0
1 1 1
输出
2
1
备注:
T<=100000
0<=a,b,c<=1000000

思路:由题可以知道每份礼物中都有a和b,当每份礼物去除掉一个a和b之后
豪华礼包:剩余c ,幸运礼包:剩余b ,普通礼包:剩余a
利用二分的方法寻找可以送出多少份礼包。

#include<cstdio>
#include<cmath>
#include<algorithm> 
using namespace std;
bool pd(int a,int b,int c,int mid){ 
    //因为每份礼物都有a和b mid份礼物就要减去mid个a和b
	a-=mid; 
	b-=mid; 
	if(a<0||b<0){ //减完后a或b有一个小于0,则不能发出mid份礼物
		return false;
	}
	if(a+b+c<mid){//减完后 a+b+c的个数要大于等于 mid份礼物
		return false;
	}
    //选出a b c的值中选最小的两个 用a和b表示
	if(a>b)swap(a,b);
	if(b>c)swap(b,c);
    //保证不相邻 则小的两个之和要大于等于mid/2
	if(a+b<mid/2) return false;
	return true;
}
int main(){
	int T;
	int a,b,c;
    scanf("%d",&T); 
    for(int i=0;i<T;i++){
        scanf("%d %d %d",&a,&b,&c);
        int l=0,r=min(a,b); //因为每份礼物都要用到一个a和一个b,这里取a和b中小的那个
        int k,mid;
        //二分查找礼物的个数
        while(l<=r){
        	mid=l+(r-l)/2;
        	if(pd(a,b,c,mid)){
        		k=mid;
        		l=mid+1;
        	}
			else{
        		r=mid-1;	
        	}
        }
        printf("%d\n",k);
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值