题目
“Ran,今天我要在Hakase家打游戏,不回来了。”
“Ran,Hakase新发明了游戏,我今天住博士家。”
“Ran,Conan今天要在我家通宵打游戏。”
终于有一天,电脑被打坏了……2333
所以Conan要前往专卖店买新的,正好专卖店正在促销,一共有三种礼包:
豪华礼包:一个 U盘、一个鼠标和一个机械键盘。
幸运礼包:一个 U盘、两个鼠标。
普通礼包:两个 U盘、一个鼠标。
卖店内准备了 a 个 U盘、b 个鼠标和 c 个机械键盘。为了给顾客带来足够多的惊喜,店长希望相邻两位领礼包的顾客拿到的礼包类型都是不同的。店长想知道这些奖品最多可以发出多少份礼包。可是店长毕竟没有Conan聪明,所以请教Conan,可是Conan要急着回去打游戏,所以就交给你啦。
对于100%的数据满足t<=100000,0<=a,b,c<=1000,000。
题解
每种礼包:
a b c
1 2 0
2 1 0
1 1 1
每种礼包都最少要消耗1个a和一个b,每个a和b都减去1后就是:
a b c
0 1 0
1 0 0
0 0 1
剩下的a,b,c就是每种礼包可以发的数量
因此对于每组a,b,c,假设要发d份礼包,最少要消耗掉d个a和d个b,a和b就都减去d
得x,y,z(x=a-d,y=b-d,z=c)就是每种礼包可以发的数量。
显然x,y,z都应大于等于0且所有礼包加起来大于计划要发的总礼包数量才能继续
此时有一个限制:“相邻两位领礼包的顾客拿到的礼包类型都是不同的”
那么最理想的发礼包方式无疑是12121323…的方式
二分答案ans
要达到这种方式,每种礼包的数量都应不大于其他两种礼包的和+1,可得:
x <= y+z+1
y <= x+z+1
z <= x+y+1
判断即可
然而我并没有做出这种判断方式的正确解法,于是自己根据这个思路又想了一种类似的解法:
(x+y)*2+1>=mid
(x+z)*2+1>=mid
(y+z)*2+1>=mid
每个都应满足
例:25 19 30 要发17份
8 2 30
x y z
323231313131313131313可以达到17份
3礼包最多,所以1和2礼包都用来跟3礼包搭配,开头或结尾可以加上1份3礼包
要判断能否达到17份可以通过判断(x+y)*2+1>=mid来确定
而18份:
7 1 30
32313131313131313无法达到18份
代码
var
a,b,c,i,t,ans,mid,l,r,x,y:longint;
begin
readln(t);
for i:=1 to t do
begin
readln(a,b,c);
ans:=0;
r:=a;if b<a then r:=b;
l:=0;
while l<=r do
begin
mid:=(l+r) div 2;
x:=a;y:=b;
a:=a-mid;b:=b-mid;
if ((a+b)*2+1>=mid)and((b+c)*2+1>=mid)and((a+c)*2+1>=mid)and(a>=0)and(b>=0)and(a+b+c>=mid)then
begin
l:=mid+1;
ans:=mid;
end else r:=mid-1;
a:=x;b:=y;
end;
writeln(ans);
end;
end.