这题一看就知道用bfs。但在做的时候有一个问题就是如何记录状态以至于不会走回原来的状态导致死循环。我们发现,数据的范围太大了,所以无论数组怎么开都会爆掉。但机智的我想到了要想最快达到目标状态,白棋只能往后走,黑棋只能往前走,所以这样的话就不会走回原来的状态。
代码有点长,不想打的可以直接cb(抄标)。
代码:
{ ID: ymwbegi1 PROG: shuttle LANG: PASCAL } var n,i,tot:longint; state:array[1..120000,-1..30] of longint; num,fa:array[1..120000] of longint; function check(x:longint):boolean; var i:longint; begin check:=true; for i:=1 to n do begin if state[x,i]<>2 then exit(false); if state[x,n+i+1]<>1 then exit(false); end; end; procedure print(x,y:longint); begin if fa[x]<>1 then print(fa[x],y); write(num[x]); inc(tot); if (tot mod 20>0)and(x<>y) then write(' '); if tot mod 20=0 then writeln; end; procedure bfs; var x,head,tail,i:longint; begin x:=0; for i:=1 to n do begin state[1,i]:=1; state[1,n+i+1]:=2; end; head:=0; tail:=1; repeat inc(head); for i:=1 to n*2+1 do begin if (state[head,i-1]=0)and(i>1)and(state[head,i]=2) then begin inc(tail); state[tail]:=state[head]; state[tail,i-1]:=state[tail,i]; state[tail,i]:=0; fa[tail]:=head; num[tail]:=i; if check(tail) then begin print(tail,tail); exit; end; end; if (state[head,i+1]=0)and(i<n*2+1)and(state[head,i]=1) then begin inc(tail); state[tail]:=state[head]; state[tail,i+1]:=state[tail,i]; state[tail,i]:=0; fa[tail]:=head; num[tail]:=i; if check(tail) then begin print(tail,tail); exit; end; end; if (state[head,i-2]=0)and(state[head,i-1]=1)and(i>2)and(state[head,i]=2) then begin inc(tail); state[tail]:=state[head]; state[tail,i-2]:=state[tail,i]; state[tail,i]:=0; fa[tail]:=head; num[tail]:=i; if check(tail) then begin print(tail,tail); exit; end; end; if (state[head,i+2]=0)and(state[head,i+1]=2)and(i<n*2)and(state[head,i]=1) then begin inc(tail); state[tail]:=state[head]; state[tail,i+2]:=state[tail,i]; state[tail,i]:=0; fa[tail]:=head; num[tail]:=i; if check(tail) then begin print(tail,tail); exit; end; end; end; until head>=tail; end; begin assign(input,'shuttle.in'); assign(output,'shuttle.out'); reset(input); rewrite(output); readln(n); bfs; if tot mod 20>0 then writeln; close(input); close(output); end.