原来这还能出成题。。。
我也不会证为什么每次都是数值最大的学生先猜出来,但感性yy一下是可以出来的。
首先一个学生猜不出来,无非就是在x+y, |x-y|中犹豫,但是我们观察发现,当x=y时,|x-y|=0,他是可以立即猜出自己的数是x+y的。
然后在想想,假如A,B,C三人的数为(x,2x,3x),如果B没有猜出来,那么C就可以肯定自己的数不是x,于是就猜出来了。
好像可以一直推下去。。。
设F(x,y,z)为猜出(x,y,z)所需要的轮数,那么F(x,y,x+y)=F[x,y,|x-y|]+1 or 2。到底是1还是2,取决于到x+y猜数还有一轮还是两轮。
写的时候这样好写,F[x,y,t]表示最大的数在t学生上,然后t后面的是x,在后面的是y,于是分x = y,x < y,x > y三种情况讨论即可。
看代码里的pd函数。
代码:
var
n,m,i,t0,t1,t2,tot:longint;
pre:array[0..2]of longint=(2,0,1);
suc:array[0..2]of longint=(1,2,0);
ans:array[0..30010,0..2]of longint;
function pd(x,y,t:longint):boolean;
var
rnd,nowx,nowy:longint;
begin
rnd:=n;
while rnd>0 do
begin
if x=y then exit(rnd=t+1);
if x>y then
begin
nowx:=y;
nowy:=x-y;
dec(rnd,2);
t:=suc[t];
end
else
begin
nowx:=y-x;
nowy:=x;
dec(rnd,1);
t:=pre[t];
end;
x:=nowx;
y:=nowy;
end;
exit(false);
end;
begin
while true do
begin
readln(n,m);
if (n=-1)and(m=-1) then break;
t1:=n mod 3;
t0:=pre[t1];
t2:=suc[t1];
tot:=0;
for i:=1 to m-1 do
if pd(i,m-i,t0) then
begin
inc(tot);
ans[tot,t0]:=m;
ans[tot,t1]:=i;
ans[tot,t2]:=m-i;
end;
writeln(tot);
if t0=1 then for i:=tot downto 1 do writeln(ans[i,0],' ',ans[i,1],' ',ans[i,2])
else for i:=1 to tot do writeln(ans[i,0],' ',ans[i,1],' ',ans[i,2]);
end;
end.