MY*****

poj 2688 Cleaning Robot

分析:状态压缩的BFS或者dfs状态+最短路。

前者就是类似于拯救大兵瑞恩的方法,后者非常经典,dfs全排列枚举然后根据最短路相加。

WA三次+TLE一次+AC。

代码:

const
  nx:array[1..4] of integer=(0,0,1,-1);
  ny:array[1..4] of integer=(1,-1,0,0);
type
  ji=record
  x,y,s,step:longint;
end;
var
  v:array[0..1027,0..24,0..24] of boolean;
  q:array[0..1000000] of ji;
  b:array[0..25,0..25] of longint;
  a:array[0..25,0..25] of char;
  sum,head,tail,s,y,x,t,step,now,n,m,i,j,k:longint;
  vv:boolean;

begin
  readln(m,n);
  while m<>0 do
    begin
      fillchar(v,sizeof(v),0);
      sum:=-1;
      for i:=1 to n do
        begin
          for j:=1 to m do
            begin
              read(a[i,j]);
              if a[i,j]='o' then
                begin
                  x:=i;
                  y:=j;
                end else
              if a[i,j]='*' then
                begin
                  inc(sum);
                  b[i,j]:=sum;
                end;
            end;
          readln;
        end;
      if sum=-1 then
        begin
          writeln(0);
          readln(m,n);
          continue;
        end;
      vv:=false;
      head:=1; tail:=1; q[1].x:=x; q[1].y:=y; v[0,x,y]:=true;
      while head<=tail do
        begin
          x:=q[head].x; y:=q[head].y; now:=q[head].s; step:=q[head].step;
          for i:=1 to 4 do
            begin
              s:=x+nx[i]; t:=y+ny[i];
              if (s<1)or(t<1)or(s>n)or(t>m) then continue;
              if a[s,t]='x' then continue;
              if a[s,t]='*' then
                begin
                  if v[now or(1<<b[s,t]),s,t] then continue;
                  inc(tail);
                  q[tail].x:=s;
                  q[tail].y:=t;
                  q[tail].s:=now or (1<<b[s,t]);
                  q[tail].step:=step+1;
                  v[q[tail].s,s,t]:=true;
                  if q[tail].s=1<<(sum+1)-1 then
                    begin
                      writeln(step+1);
                      vv:=true;
                      break;
                    end;
                  continue;
                end;
              if v[now,s,t] then continue;
              v[now,s,t]:=true;
              inc(tail);
              q[tail].s:=now;
              q[tail].x:=s;
              q[tail].y:=t;
              q[tail].step:=step+1;
            end;
          if vv then break;
          inc(head);
        end;
      if not vv then writeln(-1);
      readln(m,n);
    end;
end.

  

posted on 2011-10-20 07:50  reflec94  阅读(255)  评论(0编辑  收藏  举报

导航