MAZE题解

BFS找最短路长度

DFS找最短路总数

DFS有两个优化

f[x,y]表示到坐标为XY的点最小步数,每次递归的时候判断,如果比这个小就退出,否则更新f[x,y]

如果当前点到目标点的曼哈顿距离加上已走的步数大于BFS找出的最短长度则退出

坐标为AB和CD的两个点的曼哈顿距离为|A-C|+|B-D|

var
  fx:array[1..4,1..2]of longint=((1,0),(0,1),(-1,0),(0,-1));
  i,j,k,n,m,x,y,x1,y1,ans,min:longint;
  map:array[0..1000,0..1000]of boolean;
  f:array[1..1000,1..1000]of longint;
  d:array[1..100000,1..3]of longint;
procedure go(x1,y1,k:longint);
  var
    i:longint;
  begin
    if(x1=x)and(y1=y)and(k=min)then begin inc(ans);exit;end;
    if k>=min then exit;
    if k>f[x1,y1]then exit;
    if abs(x1-x)+abs(y1-y)+k>min then exit;
    for i:=1 to 4 do if(fx[i,1]+x1>0)and(fx[i,1]+x1<=n)and(fx[i,2]+y1>0)and(fx[i,2]+y1<=n)and map[x1+fx[i,1],y1+fx[i,2]]then go(x1+fx[i,1],y1+fx[i,2],k+1);
  end;
procedure search;
  var
    i,j,k:longint;
    a:array[0..1000,0..1000]of boolean;
  begin
    a:=map;
    a[x1,y1]:=false;
    i:=0;
    j:=1;
    d[1,1]:=x1;
    d[1,2]:=y1;
    while ido
     begin
      inc(i);
      for k:=1 to 4 do if(fx[k,1]+d[i,1]>0)and(fx[k,1]+d[i,1]<=n)and(fx[k,2]+d[i,2]>0)and(fx[k,2]+d[i,2]<=m)then
                        begin
                         inc(j);
                         d[j,1]:=fx[k,1]+d[i,1];
                         d[j,2]:=fx[k,2]+d[i,2];
                         d[j,3]:=d[i,3]+1;
                         f[d[j,1],d[j,2]]:=d[j,3];
                         if not a[d[j,1],d[j,2]]then dec(j)else
                          begin
                           a[d[j,1],d[j,2]]:=false;
                           if(d[j,1]=x)and(d[j,2]=y)then begin min:=d[j,3];exit;end;
                          end;
                        end;
     end;
  end;
begin
  read(n,m,k);
  for i:=1 to n do
   for j:=1 to m do map[i,j]:=true;
  for i:=1 to k do
   begin
    read(x,y);
    map[x,y]:=false;
   end;
  read(x1,y1,x,y);
  min:=maxlongint;
  search;
  if min=maxlongint then writeln('No Solution!')else
   begin
    go(x1,y1,0);
    writeln(min);
    write(ans);
   end;
end.

你可能感兴趣的:(MAZE题解)