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