【每日一题】2258. 逃离火灾-2023.11.9

news2024/11/27 4:36:23

题目:

2258. 逃离火灾

给你一个下标从 0 开始大小为 m x n 的二维整数数组 grid ,它表示一个网格图。每个格子为下面 3 个值之一:

  • 0 表示草地。
  • 1 表示着火的格子。
  • 2 表示一座墙,你跟火都不能通过这个格子。

一开始你在最左上角的格子 (0, 0) ,你想要到达最右下角的安全屋格子 (m - 1, n - 1) 。每一分钟,你可以移动到 相邻 的草地格子。每次你移动 之后 ,着火的格子会扩散到所有不是墙的 相邻 格子。

请你返回你在初始位置可以停留的 最多 分钟数,且停留完这段时间后你还能安全到达安全屋。如果无法实现,请你返回 -1 。如果不管你在初始位置停留多久,你 总是 能到达安全屋,请你返回 109 。

注意,如果你到达安全屋后,火马上到了安全屋,这视为你能够安全到达安全屋。

如果两个格子有共同边,那么它们为 相邻 格子。

 

解答:

二分 + BFS
火势蔓延是一个固定的过程,只有人员移动需要决策。

假设人员最晚在 t秒后出发,仍能到达安全屋,说明人员对逃走路线的访问,要比火势更快。那么人员在更早的时间点([0,t−1]秒后)出发,必然仍能按照原定路线到达安全屋(火势对路径的影响不变)。

因此,在以 ttt 为分割点的(正整数)数轴上,具有二段性,可运用「二分」求分割点。

假设存在某个判定函数 check,用于检查人员在 xxx 秒后出发能否到达安全屋,那么可知:

当实际延迟出发的秒数,小于等于 t秒,必然能安全到达
当实际延迟出发的描述,超过 t秒,必然不能安全到达
在人员移动路线中,“回头路”是没有意义的,因此人员对每个点的访问次数最多为一次。同时,不考虑墙的阻拦,火势也最多在不超过棋盘大小的时间内完全蔓延。

这指导我们最大延迟出发时间不会超过n×m,可在 [0,n×m]值域内进行二分。

接下来,考虑如何实现 check 函数,函数入参为延迟出发秒数 t,返回值为延迟出发后能否到达安全屋。

首先,对于普通位置,如果火势和人员同时到达,是不允许的,而安全屋 (n−1,m−1)位置的同时到达,是允许的。

因此,我们需要使用两个二维数组 fg 和 pg 分别记录「火势」和「人员」到达某个位置的最早时间。

创建用于模拟火势蔓延的队列 fire,遍历网格,将火源位置进行入队,更新火源位置 fg[i][j]=1,表示火势在第一秒时最早出现在此处;

运用 BFS,模拟 t秒的火势蔓延,火势在这 ttt 秒内所蔓延到的新位置,均看作为起始火源,即有 fg[i][j]=1。

若执行完 t秒后,火势已蔓延到人员起始位置 (0,0),那么延迟 t秒出发不可行,直接返回 False;

创建用于模拟人员移动的队列 people,将起始位置 (0,0)进行入队,更新 pg[0][0]=1。

运用 BFS,按照「先火后人」的方式,同步模拟「火势蔓延」和「人员移动」过程。普通位置,只要火势蔓延到,那么人将无法移动到此处;安全屋位置,需要判断是否与火势同一时刻到达。

为了方便,将「火势蔓延」和「人员移动」统一成 update 操作,入参包括当前队列 d,标识位 isFire,以及移动偏移量 offset。

在进行t秒的火势蔓延时,调用 t次的 update(fire, true, 0)。在火势和人员同步模拟时,分别调用 update(fire, true, 1) 和 update(people, false, 1)。

代码:

class Solution {
    int[][] dirs=new int[][]{{0,1},{0,-1},{1,0},{-1,0}};
    int n,m;
    boolean ok;
    int[][] g,fg,pg;
    public int maximumMinutes(int[][] grid) {
        g=grid;
        n=g.length;
        m=g[0].length;
        fg=new int[n][m];
        pg=new int[n][m];
        if(!check(0)) return -1;
        int l=0,r=n*m;
        while(l<r){
            int mid=l+r+1>>1;
            if(check(mid)) l=mid;
            else r=mid-1;
        }
        return r==m*n?(int)1e9:r;
    }
    boolean check(int t){
        ok=false;
        Deque<int[]> frie=new ArrayDeque<>();
        for(int i=0;i<n;i++){
            for(int j=0;j<m;j++){
                fg[i][j]=pg[i][j]=0;
                if(g[i][j]==1){
                    fg[i][j]=1;
                    frie.addLast(new int[]{i,j});
                }
            }
        }
        while(t-->0) upadte(frie,true,0);//先执行t秒的火势蔓延
        if(fg[0][0]!=0) return false;
        Deque<int[]> people=new ArrayDeque<>();
        pg[0][0]=1;
        people.addLast(new int[]{0,0});
        while(!people.isEmpty()){
            //先火后人,同步进行
            upadte(frie,true,1);
            upadte(people,false,1);
            if(ok) return true;
        }
        return false;
    }
    void upadte(Deque<int[]> deque,boolean isFire,int offset){
        int sz=deque.size();
        while(sz-->0){
            int[] info=deque.pollFirst();
            int x=info[0],y=info[1];
            for(int[] dir:dirs){
                int nx=x+dir[0],ny=y+dir[1];
                if(nx<0||nx>=n||ny<0||ny>=m) continue;
                if(g[nx][ny]==2) continue;
                if(isFire){
                    if(fg[nx][ny]!=0) continue;
                    fg[nx][ny]=fg[x][y]+offset;
                }else{
                    if(nx==n-1&&ny==m-1&&(fg[nx][ny]==0||fg[nx][ny]==pg[x][y]+offset))
                        ok=true;//火尚未达到或同时到达
                    if(fg[nx][ny]!=0||pg[nx][ny]!=0) continue;
                    pg[nx][ny]=pg[x][y]+offset;
                }
                deque.addLast(new int[]{nx,ny});
            }
        }
    }
}

结果:

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1188474.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

LeetCode【78. 子集】

78. 子集 中等 2.2K 相关企业 给你一个整数数组 nums &#xff0c;数组中的元素 互不相同 。返回该数组所有可能的子集&#xff08;幂集&#xff09;。 解集 不能 包含重复的子集。你可以按 任意顺序 返回解集。 示例 1&#xff1a; 输入&#xff1a;nums [1,2,3] 输出&…

Frp内网穿透部署

Frp内网穿透部署记录windows为例 A固定外网IP服务器一台&#xff08;可以映射端口&#xff09;B内网PC一台&#xff0c;可上外网 A固定外网IP服务器一台&#xff08;可以映射端口&#xff09; B内网PC一台&#xff0c;可上外网 GO语言&#xff1a;https://golang.org/doc/ins…

如何用CHAT 写会后总结

问CHAT&#xff1a;阐述参加IMS系统培训课程的收益和不学的损失。 CHAT 回复&#xff1a; 参加IMS系统培训课程的收益&#xff1a; 1. 提升技能和知识&#xff1a;通过参加IMS系统培训课程&#xff0c;你可以学习到刚新的信息技术和知识&#xff0c;增强你的技能和经验&…

UART编程(寄存器)

1. 串口编程步骤 1.1 看原理图确定引脚 有很多串口&#xff0c;使用哪一个&#xff1f;看原理图确定 1.2 配置引脚为UART功能 至少用到发送、接收引脚&#xff1a;txd、rxd 需要把这些引脚配置为UART功能&#xff0c;并使能UART模块 1.3 设置串口参数 有哪些参数&#xf…

Leecode刷题【hot100】盛最多水的容器

给定一个长度为 n 的整数数组 height 。有 n 条垂线&#xff0c;第 i 条线的两个端点是 (i, 0) 和 (i, height[i]) 。 找出其中的两条线&#xff0c;使得它们与 x 轴共同构成的容器可以容纳最多的水。 返回容器可以储存的最大水量。 说明&#xff1a;你不能倾斜容器。 示例…

linux生成code文件

1. 设置core文件路径在当前工作目录 echo "core-%e-%p-%t" > /proc/sys/kernel/core_pattern 具体参数 %s - insert signal that caused the coredump into the filename 添加导致产生core的信号 %t - insert UNIX time that the coredump occurred into filen…

使用 Wireshark 抓包工具快速分析 IoT 物联网终端设备的网络通信行为

当你进行 IoT 物联网开发过程中&#xff0c;终端-MQTT 服务器-业务系统-App 全链路联调时往往难以快速定位问题&#xff1a;终端可能未正常发出消息报文&#xff0c;也可能在网络传输中丢失&#xff0c;也可能被 MQTT 服务器限流丢弃&#xff0c;或者业务系统处理异常而丢失。此…

Centos7安装宝塔面板8.0.3并实现公网远程登录宝塔面板【内网穿透】

Centos7安装宝塔面板8.0.3并实现公网远程登录宝塔面板【内网穿透】 文章目录 Centos7安装宝塔面板8.0.3并实现公网远程登录宝塔面板【内网穿透】一、使用官网一键安装命令安装宝塔二、简单配置宝塔&#xff0c;内网穿透三、使用固定公网地址访问宝塔 宝塔面板作为建站运维工具&…

flink1.18.0 sql-client报错

报错 Flink SQL> select * from t1; [ERROR] Could not execute SQL statement. Reason: org.apache.flink.table.api.ValidationException: Could not find any factory for identifier kafka that implements org.apache.flink.table.factories.DynamicTableFactory in t…

如何搭建一个自定义UI框架的Playground(一)

文章目录 初衷需求技术选型详细设计&#xff08;一&#xff09;1.业务设计2.交互设计3.程序设计3.1 游戏生命周期设计3.2 UI界面管理设计 初衷 想要比较系统、深入地了解游戏UI框架的设计与开发&#xff0c;就需要自己实践去开发一个可以预览的UI项目&#xff0c;但是目前没有…

OpenTiny Vue 组件库支持 Vue2.7 啦!

之前 OpenTiny 发布了一篇 Vue2 升级 Vue3 的文章。 &#x1f596;少年&#xff0c;该升级 Vue3 了&#xff01; 里面提到使用了 ElementUI 的 Vue2 项目&#xff0c;可以通过 TinyVue 和 gogocode 快速升级到 Vue3 项目。 有朋友评论替换button出错了&#xff0c;并且贴出了…

K8S篇之etcd数据备份与恢复

一、etcd备份与恢复 基本了解&#xff1a; 1、k8s 使用etcd数据库实时存储集群中的数据&#xff0c;安全起见&#xff0c;一定要备份。 2、备份只需要在一个节点上备份就可以了&#xff0c;每个节点上的数据是同步的&#xff1b;但是数据恢复是需要在每个节点上进行。 3、etcd…

性能测试从0到1

性能测试概念 我们经常看到的性能测试概念&#xff0c;有人或称之为性能策略&#xff0c;或称之为性能方法&#xff0c;或称之为性能场景分类&#xff0c;大概可以看到性能测试、负载测试、压力测试、强度测试等一堆专有名词的解释。 针对这些概念&#xff0c;我不知道你看到…

AppWeb 身份验证绕过漏洞 (CVE-2018-8715)漏洞复现

漏洞描述 AppWeb 是一个嵌入式 Web 服务器&#xff0c;基于由 Embedthis Software LLC 开发和维护的开源 GPL 协议。它是用C / C编写的&#xff0c;几乎可以在任何现代操作系统上运行。当然&#xff0c;它旨在为嵌入式设备提供一个 Web 应用程序容器。 AppWeb 可以配置为身份…

lua 时间差功能概略

简介 在进行程序设计过程中&#xff0c;经常需要对某些函数、某些程序片断从开始运行到运行结束所耗费的时间进行一些量化。这种量化实际上就是计算时间差。 获取函数耗时情景如下&#xff1a; function time_used() --开始计时-- do something at here. --结束计时--时间差&…

kubernetes集群编排——k8s资源监控

资源限制 上传镜像 [rootk8s2 limit]# vim limit.yaml apiVersion: v1 kind: Pod metadata:name: memory-demo spec:containers:- name: memory-demoimage: stressargs:- --vm- "1"- --vm-bytes- 200Mresources:requests:memory: 50Milimits:memory: 100Mi [rootk8s2…

Kotlin系列之注解详解

目录 注解&#xff1a;file:JvmName 注解&#xff1a;JvmField 注解&#xff1a;JvmOverloads 注解&#xff1a;JvmStatic 注解&#xff1a;JvmMultifileClass 注解&#xff1a;JvmSynthetic 注解&#xff1a;file:JvmName file:JvmName(“XXX”) 放在类的最顶层&#x…

基于51单片机蓝牙智能控制风扇-proteus仿真-源程序

基于51单片机蓝牙智能控制风扇-proteus仿真-源程序 一、系统方案 1、本设计采用51单片机作为主控器。 2、DS18B20采集温度值送到液晶1602显示。 3、按键设置上下限&#xff0c;自动模式&#xff0c;低于下限&#xff0c;风扇不启动&#xff0c;下限到上限之间&#xff0c;风扇1…

开源知识库软件xwiki在Windows下的安装

文章目录 开源知识库软件-xwiki在windows上的部署0、参考文档1、前置环境准备1.1、Windows版本及系统配置1.2、JDK11安装1.3、Tomcat9安装1.4、MySQL5.7数据库的安装 2、xwiki安装3、配置3.1、修改配置支持对文档内容进行搜索 4、问题解决4.1、附件无法上传问题4.1、附件无法下…

快速搭建开源分布式任务调度系统DolphinScheduler并远程访问

使用Docker部署开源分布式任务调度系统DolphinScheduler 文章目录 使用Docker部署开源分布式任务调度系统DolphinScheduler前言1. 安装部署DolphinScheduler1.1 启动服务 2. 登录DolphinScheduler界面3. 安装内网穿透工具4. 配置Dolphin Scheduler公网地址5. 固定DolphinSchedu…