[mr440] 崎岖的山区

极类似动归的广搜?反正各种算法傻傻分不清…写之前叹了一句,好久不写广搜了啊!呵呵真的写了好久,大约一个钟头?

f[i,j,0]表示到点(i,j)且最后一步为下降的最少步数,f[i,j,1]就是上升。莫名让我想到了NOIP2013的摆花,那时我也脑坏地写了个O(N^2)也是这样[1..n,1..n,0..1]的数组…

犯的错误就是由于判断更高之后要入队列,判断更低之后也要入队列,否则有可能前面的true被后面的false给搞掉…这就是为什么我过了三个数据,剩下的数据都只错了一两行的原因。(数据真弱=。=)

90行+广搜,有种hold不住的感觉。今天上课听了树链剖分我表示…那种题遇到了干脆就送掉吧…=y=能搞懂LCA就是万幸了。

program mr440;
const dx:array[1..4] of integer=(1,0,-1,0);
      dy:array[1..4] of integer=(0,-1,0,1);
var map:array[0..101,0..101] of integer;
    mark:array[0..101,0..101] of boolean;
    m,n,i,j,l,r,tx,ty:longint;
    f:array[0..101,0..101,0..1] of longint;
    lx,ly:array[1..1000000] of integer;
    flag:boolean;

function min(a,b:longint):longint;
begin
  if a>b then exit(b) else exit(a);
end;

function min3(a,b,c:longint):longint;
begin
  if (a<b) and (a<c) then exit(a);
  if (b<c) and (b<a) then exit(b);
  exit(c);
end;

begin
  assign(input,'mr440.in2');reset(input);
  assign(output,'mr440.ou2');rewrite(output);
  readln(m,n);
  for i:=1 to m do
    begin
      for j:=1 to n do
        read(map[i,j]);
      readln;
    end;
  fillchar(mark,sizeof(mark),0);
  fillchar(f,sizeof(f),$7f);
  l:=1;r:=1;lx[l]:=0;ly[l]:=0;mark[0,0]:=true;f[0,0,0]:=0;f[0,0,1]:=0;
  while (l<=r) do
    begin
      for i:=1 to 4 do
        begin
          tx:=lx[l]+dx[i];
          ty:=ly[l]+dy[i];
          if (tx<0) or (tx>m+1) or (ty<0) or (ty>n+1) then continue;
          if map[tx,ty]>=map[lx[l],ly[l]] then {1 shangsheng}
            begin
              flag:=false;
              if f[lx[l],ly[l],1]<f[tx,ty,1] then
                begin
                  f[tx,ty,1]:=f[lx[l],ly[l],1];
                  flag:=true;
                end;
              if f[lx[l],ly[l],0]+1<f[tx,ty,1] then
                begin
                  f[tx,ty,1]:=f[lx[l],ly[l],0]+1;
                  flag:=true;
                end;
              if (mark[tx,ty]=false) and (flag=true) then
                begin
                  inc(r);
                  lx[r]:=tx;ly[r]:=ty;
                  mark[tx,ty]:=true;
                end;
            end;
          if map[tx,ty]<=map[lx[l],ly[l]] then
            begin
              flag:=false;
              if f[lx[l],ly[l],0]<f[tx,ty,0] then
                begin
                  f[tx,ty,0]:=f[lx[l],ly[l],0];
                  flag:=true;
                end;
              if f[lx[l],ly[l],1]+1<f[tx,ty,0] then
                begin
                  f[tx,ty,0]:=f[lx[l],ly[l],1]+1;
                  flag:=true;
                end;
              if (mark[tx,ty]=false) and (flag=true) then
                begin
                  inc(r);
                  lx[r]:=tx;ly[r]:=ty;
                  mark[tx,ty]:=true;
                end;
            end;
        end;
      mark[lx[l],ly[l]]:=false;
      inc(l);
    end;
  for i:=1 to m do
    begin
      write(min(f[i,1,1]+f[i,1,0],min(f[i,1,1],f[i,1,0])*2+1),' ');
      for j:=2 to n do
        write(min(f[i,j,1]+f[i,j,0],min(f[i,j,1],f[i,j,0])*2+1),' ');
      writeln;
    end;
  close(input);close(output);
end.
崎岖的山区
原文地址:https://www.cnblogs.com/Sky-Grey/p/3575804.html