nowcoder---常州大学新生寒假训练会试----F 大佬的生日礼包(二分)
链接:https://www.nowcoder.net/acm/contest/78/F
时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 32768K,其他语言65536K
64bit IO Format: %lld
64bit IO Format: %lld
题目描述
今天是某不愿透露姓名的谈姓大佬的生日,转发这场比赛到三个群就可以,获得以下三种礼包之一。
豪华礼包:一个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、c够不够组成达到这个答案的长度呢
当前验证答案为mid
观察到每一份礼包都有至少一个a一个b,先给这些每一个分一个a一个b
那么剩下的a、b、c 分给每个位置一个什么东西就决定了这个位置属于什么礼包
问题就变成了剩下的abc能不能构成长度为mid,相邻不同的一个序列
当剩余的abc中某个为负数那肯定这个答案是不行了
能不能组成,假如我们给abc排个序使得a<=b<=c的话,假如a+b>=c那么能组成的最长长度为a+b+c(自己画个图)
如果a+b<c,那么能组成的最长度就是(2*(a+b))+1(有剩余可以加到末尾)
我们当然可以通过这种方式计算出最长的长度然后来判断
此外,对于答案mid,能不能达到,就看abc中最小两个相加能不能>=mid/2
/////////////////////////////////////
贴代码
1 #include <bits/stdc++.h> 2 #define mst(a,b) memset((a),(b), sizeof a) 3 #define lowbit(a) ((a)&(-a)) 4 #define IOS ios::sync_with_stdio(0);cin.tie(0); 5 using namespace std; 6 typedef long long ll; 7 const int mod=1e9+7; 8 const int maxn=1e5+10; 9 int main(){ 10 #ifdef local 11 //freopen("in.txt","r",stdin); 12 //freopen("out.txt","w",stdout); 13 #endif 14 int t;scanf("%d",&t); 15 while(t--){ 16 int a,b,c;scanf("%d%d%d",&a,&b,&c); 17 int ans=0,l=0,r=3e6; 18 while(l<=r){ 19 int mid=(l+r)>>1; 20 int aa=a-mid,bb=b-mid,cc=c; 21 if(aa>=0&&bb>=0&&(aa+bb+cc)>=mid&& 22 (aa+bb)>=(mid>>1)&&(aa+cc)>=(mid>>1)&&(bb+cc)>=(mid>>1)){ 23 ans=mid;l=mid+1; 24 }else r=mid-1; 25 } 26 printf("%d\n",ans); 27 } 28 return 0; 29 }