题目
https://nanti.jisuanke.com/t/11214
题目描述
联想专卖店准备进行大促销,每位进店购买电脑的顾客都能获得奖品大礼包。一共有三种备选奖品:U盘、鼠标和机械键盘。一共有三种礼包配置:
豪华礼包:一个 U盘、一个鼠标和一个机械键盘。
幸运礼包:一个 U盘、两个鼠标。
普通礼包:两个 U盘、一个鼠标。
现在专卖店内准备了 aa 个 U盘、bb 个鼠标和 cc 个机械键盘。为了给顾客带来足够多的惊喜,店长希望 相邻两位领礼包的顾客拿到的礼包类型都是不同的。店长想知道这些奖品最多可以发出多少份礼包。
输入格式
第一行一个正整数 (1≤T≤10^5 ) 表示数据的组数。
每组数据一行三个正整数 a,b,c(0≤c≤b≤a≤10^5 ),表示 U盘、鼠标和机械键盘各有多少个。
所有 a,b,c 的总和不超过 10^7 。
输出格式
每组数据输出一个整数,表示最多能发出多少份礼包。
样例输入
2
4 4 0
1 1 1样例输出
2
1
分析
- 可以发现三种礼包都包含一个鼠标和一个U盘,然后三种礼包是外加一个U盘或鼠标或键盘。
- 二分一下答案,那么剩下
a-mid
个U盘,b-mid
个鼠标,c
个键盘,判断一下这些可不可以摆成一个长度不小于mid
的相邻两个不相等的数列即可。(具体判断方法思考一下,程序中那种仅供参考,有其他方法也行)
程序
#include <cstdio>
#include <algorithm>
using namespace std;
int T,a,b,c,l,r,mid,ans;
bool ok(int x,int y,int z){
if (x>z+y) return 2*(z+y)+1>=mid;
return z+y+x>=mid;
}
int main(){
scanf("%d",&T);
while (T--){
scanf("%d%d%d",&a,&b,&c);
l=0,r=min(a,b);
while (l<=r){
mid=(l+r)>>1;
int A=a-mid,B=b-mid,C=c;
if (ok(max(A,max(B,C)),A+B+C-max(A,max(B,C))-min(A,min(B,C)),min(A,min(B,C)))) l=mid+1,ans=mid;
else r=mid-1;
}
printf("%d\n",ans);
}
}