题目
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);
}
}