June 11th 模拟赛B T2 翻山越岭 Solution

空降题目处
点我点我点我

Description:

这里是小X的节目《荒野求生》,小X将要穿越一座山脉,这座山脉可用一个N*M的矩阵a来表示,其中a[i,j]为(i,j)地区的海拔。小X现在在(1,1)地区,他准备前往(N,M)地区。由于小X不会凯文的瞬间移动,所以只能从一个地区向上,下,左,右四个方向移动,到达一个临近的地区。
为了节省体力,小X从起点前往终点的这段路径中,最高海拔与最低海拔之差要尽量小,于是他请你帮忙求出最优的路径,使得海拔差最小,并输出这个差值。

Input

第一行为两个正整数N,M。
接下来N行每行M个整数,表示整个矩阵。

Output

输出仅一行,为所求的答案。

Solution

还是神奇的二分
若有路径 p ,则 Ans=min(maxpminp) .
UpSet=maxp,DownSet=minp ,
则可枚举 UpSet (JudgeUpSet=true) ,二分 DwonSet ,更新 Ans=UpSetDownSet .
利用Bfs检测 DownSet 合法性。


Special

JudgeDi,j=true
minDUpSetmin(D1,1,Dn,m)


Program

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.

你可能感兴趣的:(造福人类,题解)