题意:一个猜数游戏,规则如下:
1、主持人在[a.b]中随机想一个数x,并告诉选手a和b
2、选手猜的数为y,如果y=x则猜中
如果y<x则提示小了
如果y>x则主持人不再说话,只用摇头和点头表示选手是否猜对
求在最坏情况下至少猜几次能猜对
首先我们发现,a和b并没有什么用,只是告诉你需要在(num=b-a+1)个数中猜出正确答案
我们假设第一次猜的数是z,那么如果z>x那么我们最坏总共要猜z次,如果z<x那么我们继续向大猜。目前我们在最坏情况下至少要猜z次,那么我们保证总次数<=z,
所以下一次猜的数,我们要修改步长,如果我们猜2z的话,如果2z>x了,那么最坏情况下我们需要再猜(z-1)次,那么我们总共猜了(z-1+2=z+1)次。所以我们第二次猜的步长为(z-1),猜的数为(z+(z-1)=2z-1)。这样即使2z-1>x我们最坏只需要猜(z-2)次,总次数为z次。
同理第三次猜的步长为(z-2),猜的数为(3z-3)...最后我们的步长缩小到1
由于要求最少次数,所以我们不能出现我们步长缩到1后依旧没有到b(没有覆盖整个猜数区间),不然我们到最后会出现1、1 、1 、1......,反而增多了猜数的次数
那么我们总的猜数长度tot=z+z-1+z-2+...+2+1=z*(z+1)/2 ,应该大于等于num
即 tot>=num
解出最小整数解,z即为答案
体现从小到大为枚举整数解,一个满足不等式的就break输出答案
做题的时候脑子已经下线....= =
var
x1,x2,a,b,num :longint;
i :longint;
begin
read(a,b);
num:=b-a+1;
x1:=0;
for i:=1 to 3500 do
begin
x2:=x1+i;
if (num<=x2) and (num>x1) then break;
x1:=x2;
end;
writeln(i);
end.
——by Eirlys