P1825 玉米田迷宫

有了上次题目看错的教训后再不敢随便看题了usaco太坑,这题绝对不水,传送门还特别玄学自然代码短不了…
代码:

const z:array[1..4,1..2]of -1..1=((1,0),(0,1),(-1,0),(0,-1));
var i,j,k:longint;
    m,n:longint;
    pdx,pdy:longint;
    csmx,csmy:array['A'..'Z',0..1]of longint;
    a,boo:array[-1..1000,-1..1000]of boolean;
    b:array[-1..1000,0..1000]of longint;
    h,t:longint;
    ch:char;
    fx,fy,lx,ly:longint;
    x,y,u,p:array[0..4000000]of longint;//开大一点
begin
  readln(m,n);
  for i:=1 to m do
  begin
    for j:=1 to n do
    begin
      read(ch);
      if ch='@' then
      begin
        fx:=i;
        fy:=j;
        a[i,j]:=false;
      end;
      if ch='=' then
      begin
        lx:=i;
        ly:=j;
        a[i,j]:=true;
      end;
      if ch='#' then
      begin
        a[i,j]:=false;
      end;
      if ch='.' then
      begin
        a[i,j]:=true;
      end;
      if ch in ['A'..'Z'] then//判断传送门
      begin
        a[i,j]:=true;
        if csmx[ch,0]<>0 then//如果还没有找到同字母的传送门
        begin
          csmx[ch,1]:=i;
          csmy[ch,1]:=j;
          b[i,j]:=ord(ch)*10;
        end
        else//找到过了
        begin
          csmx[ch,0]:=i;
          csmy[ch,0]:=j;
          b[i,j]:=ord(ch)*10+1;
        end;
      end
      else
      b[i,j]:=0;
    end;
    readln;
  end;
  h:=1;
  t:=1;
  u[1]:=0;
  x[1]:=fx;
  y[1]:=fy;
  repeat
    if (x[t]=lx) and (y[t]=ly) then
    begin
      writeln(u[t]);
      exit;
    end;
    if (b[x[t],y[t]]<>0) and (p[t]=0) then//因为有传送门必须走,所以直接修改尾巴上的值
    if (a[csmx[chr(b[x[t],y[t]] div 10),b[x[t],y[t]] mod 10],
          csmy[chr(b[x[t],y[t]] div 10),b[x[t],y[t]] mod 10]]) then//感觉有点眼酸...
    begin
      pdx:=csmx[chr(b[x[t],y[t]] div 10),b[x[t],y[t]] mod 10];//记录
      pdy:=csmy[chr(b[x[t],y[t]] div 10),b[x[t],y[t]] mod 10];
      x[t]:=pdx;
      y[t]:=pdy;
      p[t]:=1;
    end;
    if (b[x[t],y[t]]=0) or (p[t]=1) then//接下来就很简单了
    for i:=1 to 4 do
    if a[x[t]+z[i,1],y[t]+z[i,2]] then
    begin
      inc(h);
      x[h]:=x[t]+z[i,1];
      y[h]:=y[t]+z[i,2];
      p[h]:=0;
      u[h]:=u[t]+1;
      if b[x[h],y[h]]=0 then//有传送门不可以赋为false,因为可能这只是一个中转站
      a[x[h],y[h]]:=false;
    end;
    inc(t);
  until t>h;
end.

如果不理解

有传送门不可以赋为false,因为可能这只是一个中转站

则举一个例子

###=###
#.....#
###A###
#.....#
#@#####
###a..#
#######

a,A一对传送门。
要先进入A从a出来,再进人a从A出来,不然不可以到终点,a就是一个中转站。

  • 这可能才是本题考点。

猜你喜欢

转载自blog.csdn.net/sxy__orz/article/details/85038060
今日推荐