June 11th 模拟赛B T1 刺杀大使 Solution

本文介绍了一个关于寻找最小伤害路径的问题。在一个由多个房间组成的迷宫中,每个房间可能对进入者造成不同的伤害。文章详细解释了如何使用二分搜索结合广度优先搜索的方法来确定最低的伤害值,并提供了完整的伪代码实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

空降题目处
点我点我点我

Description:

伊朗伊斯兰革命卫队(某恐怖组织)正在策划一起刺杀行动,他们的目标是沙特驻美大使朱拜尔。他们来到了沙特驻美使馆,准备完成此次刺杀,要进入使馆首先必须通过使馆前的防御迷阵。
迷阵一个由n*m个相同的小房间组成,每个房间与相邻四个房间之间有门可通行。在第n行的m个房间里有m个机关,这些机关必须全部被打开才可以进入大使馆。而第1行的m个房间有m扇向外开的门,是迷阵的入口。除了第1行和第n行的房间外,每个房间都被使馆的安保人员安装了激光杀伤装置,将会对进入房间的人造成一定的伤害。第i行第j列造成的伤害值为p[i][j](第1行和第n行的p值全部为0)。
现在伊斯兰革命卫队打算以最小伤害代价进入迷阵,打开全部机关,显然,他们可以选择任意多的人从任意的门进入,但必须到达第n行的每个房间。一个士兵受到的伤害值为他到达某个机关的路径上所有房间的伤害值中的最大值,整个部队受到的伤害值为所有士兵的伤害值中的最大值。现在,这个恐怖组织掌握了迷阵的情况,他们需要提前知道怎么安排士兵的行进路线可以使得整个部队的伤害值最小。

Input

第一行有两个整数n,m,表示迷阵的大小。
接下来有n行,每行m个数,第i行第j列的数表示p[i][j]。

Output

输出一个数,表示最小伤害代价。

Solution

传说中的二分神器
我们来看看样例数据。

Tables1列2列
1行00
2行35
3行24
4行00

由此看出,我们只需要走到第 n 行任意位置,即可走完所有且不花费。(废话)
由此,我们可以二分答案,Bfs检验(pi,j<mid时,即代表此格可以走)。

Program

var
    n,m,i,j:longint;
    data:array [1..1000001,1..2] of longint;
    p:array [0..1001,0..1001] of longint;
    move:array [1..4,1..2] of longint=((0,1),(1,0),(-1,0),(0,-1));

function Bfs(x:longint):boolean;
var
    bj:array [1..1000,1..1000] of boolean;
    i,j,k:longint;

begin

    fillchar(bj,sizeof(bj),true);
    for i:=1 to m do
    begin
        data[i,1]:=1;
        data[i,2]:=i;
        bj[1,i]:=false;
    end;
    i:=0;
    j:=m;
    while i<j do
    begin
        inc(i);
        for k:=1 to 4 do
            if (p[data[i,1]+move[k,1],data[i,2]+move[k,2]]<=x) and (bj[data[i,1]+move[k,1],data[i,2]+move[k,2]]) then
            begin
                if data[i,1]+move[k,1]=n then
                    exit(true);
                inc(j);
                data[j,1]:=data[i,1]+move[k,1];
                data[j,2]:=data[i,2]+move[k,2];
                bj[data[i,1]+move[k,1],data[i,2]+move[k,2]]:=false;
            end;
    end;

    exit(false);

end;

function GA(l,r:longint):longint;
var
    mid:longint;

begin

    if l>=r then
        exit(l);
    mid:=(l+r) shr 1;
    if Bfs(mid) then
        exit(GA(l,mid))
    else
        exit(GA(mid+1,r));

end;

begin



    readln(n,m);
    fillchar(p,sizeof(p),$7f);
    for i:=1 to n do
    begin
        for j:=1 to m do
            read(p[i,j]);
        readln;
    end;
    writeln(GA(1,1000));

    close(input);
    close(output);

end.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值