9.2 游戏 2714(9.4)

来源:互联网 发布:餐饮订餐软件 编辑:程序博客网 时间:2024/06/11 20:54

  • 题目
  • 题解
  • 代码

题目

“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  z323231313131313131313可以达到17份3礼包最多,所以1和2礼包都用来跟3礼包搭配,开头或结尾可以加上1份3礼包要判断能否达到17份可以通过判断(x+y)*2+1>=mid来确定而18份:    7  1  3032313131313131313无法达到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.
原创粉丝点击