空降题目处
点我点我点我
这里是小X的节目《荒野求生》,小X将要穿越一座山脉,这座山脉可用一个N*M的矩阵a来表示,其中a[i,j]为(i,j)地区的海拔。小X现在在(1,1)地区,他准备前往(N,M)地区。由于小X不会凯文的瞬间移动,所以只能从一个地区向上,下,左,右四个方向移动,到达一个临近的地区。
为了节省体力,小X从起点前往终点的这段路径中,最高海拔与最低海拔之差要尽量小,于是他请你帮忙求出最优的路径,使得海拔差最小,并输出这个差值。
第一行为两个正整数N,M。
接下来N行每行M个整数,表示整个矩阵。
输出仅一行,为所求的答案。
还是神奇的二分
若有路径 p ,则 Ans=min(maxp−minp) .
设 UpSet=maxp,DownSet=minp ,
则可枚举 UpSet (JudgeUpSet=true) ,二分 DwonSet ,更新 Ans=UpSet−DownSet .
利用Bfs检测 DownSet 合法性。
JudgeDi,j=true
minD≤UpSet≤min(D1,1,Dn,m)
uses
math;
var
n,m,i,j,ans,mn,mx:longint;
ju:array [1..10000] of boolean;
data:array [1..10001,1..2] of longint;
p:array [0..101,0..101] of longint;
bj:array [0..101,0..101] of boolean;
move:array [1..4,1..2] of longint=((0,1),(1,0),(-1,0),(0,-1));
function Bfs(x,y:longint):boolean;
var
i,j,k,a,b:longint;
begin
fillchar(bj,sizeof(bj),true);
data[1,1]:=1;
data[1,2]:=1;
bj[1,1]:=false;
if (x>p[1,1]) or (p[1,1]>y) then
exit(false);
i:=0;
j:=1;
while ido
begin
inc(i);
for k:=1 to 4 do
begin
a:=data[i,1]+move[k,1];
b:=data[i,2]+move[k,2];
if (x<=p[a,b]) and (p[a,b]<=y) and (bj[a,b]) then
begin
if (a=n) and (b=m) then
exit(true);
inc(j);
data[j,1]:=a;
data[j,2]:=b;
bj[a,b]:=false;
end;
end;
end;
exit(false);
end;
function GA(l,r:longint):longint;
var
mid:longint;
begin
if l>=r then
begin
if Bfs(i,l) then
exit(l)
else
exit(maxlongint);
end;
mid:=(l+r) shr 1;
if Bfs(i,mid) then
exit(GA(l,mid))
else
exit(GA(mid+1,r));
end;
begin
readln(n,m);
fillchar(p,sizeof(p),$7f);
mn:=maxlongint;
for i:=1 to n do
begin
for j:=1 to m do
begin
read(p[i,j]);
ju[p[i,j]]:=true;
mx:=max(mx,p[i,j]);
mn:=min(mn,p[i,j]);
end;
end;
ans:=maxlongint;
for i:=mn to min(p[1,1],p[n,m]) do
begin
if ju[i] then
ans:=min(ans,GA(i,mx)-i);
end;
writeln(ans);
close(input);
close(output);
end.