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.

  

你可能感兴趣的:(robot)