USACO 4.4 Shuttle Puzzle bfs

这题一看就知道用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.


你可能感兴趣的:(USACO 4.4 Shuttle Puzzle bfs)