AI刷题-病毒在封闭空间中的传播时间

news2025/1/21 6:16:14

目录

问题描述

输入格式

输出格式

解题思路:

问题理解

数据结构选择

算法步骤

代码实现: 

1.初始化: 

2.设置边界条件: 

3.判断 

4.更新: 

 5.返回

 最终的实现代码如下:

运行结果: 

 


以后我想试着一篇博客就写一道题解,尽可能的地把题解思路讲清楚(ps:因为我昨天看之前写的题解的时候有点云里雾里,这就违背我写题解的初衷了)

问题描述

在一个封闭的房间里摆满了座位,每个座位东西向和南北向都有固定 1 米的间隔。座位上坐满了人,坐着的人可能带了口罩,也可能没有带口罩。我们已经知道房间里的某个人已经感染了病毒,病毒的传播速度是每秒钟感染距离 1 米,但是超出 1 米病毒没有感染效力。病毒对于戴口罩的人需要两秒钟,或者一秒内被周围的两个人分别感染一次,才能被病毒感染。请实现一个算法,计算出来在给定的人员戴口罩情况,以及已经感染的人员位置情况下,病毒感染屋内所有人所需的时间。假定,已经感染的人戴和不戴口罩都具有相同的感染能力。

输入格式

第一行两个整数 n, m,表示座位有 n 行 m 列

接下来 n 行,每行 m 个整数 T(i, j)表示座位上的人戴口罩情况,0 表示未戴口罩,1 表示戴了口罩

最后一行两个整数 x, y 表示已经感染病毒的人所在座位

输出格式

输出一个整数表示病毒感染屋内所有人所需的时间

输入样例

4 4

0 1 1 1

1 0 1 0

1 1 1 1

0 0 0 1

2 2

输出样例

6

数据范围

座位横向和纵向最多 255

解题思路:

问题理解

  1. 房间布局:房间是一个 n x m 的二维网格,每个格子代表一个座位。
  2. 口罩情况:每个座位上的人可能有口罩(1)或没有口罩(0)。
  3. 病毒传播规则
    • 病毒每秒可以传播到距离为1米的座位。
    • 未戴口罩的人(0)在1秒内被感染。
    • 戴口罩的人(1)需要2秒或被周围的两个人分别感染一次才能被感染。
  4. 初始感染者:给定一个初始感染者的位置 (x, y)

数据结构选择

  1. 二维数组:用于表示房间的座位布局和每个人的口罩情况。
  2. 队列:用于广度优先搜索(BFS),记录当前时间步内需要处理的感染者。
  3. 时间记录:用于记录每个座位被感染的时间。

算法步骤

  1. 初始化

    • 创建一个二维数组 time 记录每个座位被感染的时间,初始值为 -1 表示未被感染。
    • 将初始感染者的位置 (x, y) 加入队列,并设置 time[x][y] = 0
  2. 广度优先搜索(BFS)

    • 从队列中取出当前时间步的感染者。
    • 检查其四个方向(上、下、左、右)的邻居:
      • 如果邻居未被感染且未戴口罩(0),则将其感染时间设置为当前时间步加1,并加入队列。
      • 如果邻居未被感染且戴口罩(1),则需要特殊处理:
        • 如果当前时间步加1等于2秒,或者当前时间步加1等于1秒且有两个邻居已经感染,则将其感染时间设置为当前时间步加1,并加入队列。
  3. 终止条件

    • 当队列为空时,表示所有可能被感染的座位都已经被处理。
  4. 结果输出

    • 返回 time 数组中的最大值,即为病毒感染屋内所有人所需的时间。

代码实现: 

1.初始化: 

我们单独创建directions作为四个方向的偏移量,queue作为bfs算法的队列,infected_time作为时间数组记录当前病人感染时间

同时获取被感染人的坐标,插入队列,并将时间轴设为0;

std::vector<std::pair<int, int>> directions = {
  
  {0, 1}, {1, 0}, {0, -1}, {-1, 0}};
std::queue<std::tuple<int, int, int>> queue;
std::vector<std::vector<int>> infected_time(row_n, std::vector<int>(column_m, std::numeric_limits<int>::max()));

int start_row = patient[0];
int start_col = patient[1];
queue.push({start_row, start_col, 0});  // (行, 列, 时间)
infected_time[start_row][start_col] = 0;

2.设置边界条件: 

0 <= nr && nr < row_n && 0 <= nc && nc < column_m 

3.判断 

 如果此时该坐标的人未带口罩,则seats[nr][nc] == 0,反之则是戴口罩,对此有两种不同的判定:

对于前者:只需将时间数组自增便感染成功

对于后者:需要对当前时间进行2秒的自增,然后判断当前位置的周围是否有大于等于2的感染者,

此时如果满足该条件,则进行特殊处理,即当前位置的病人需要比较是前面自增两秒的的感染时间少还是存在两名以上感染者感染他的时间少。 不过我这是觉得直接处理成time+1就行了,应该是必定大于前者的

                int new_time;
                if (seats[nr][nc] == 0) {  // 未戴口罩
                    new_time = time + 1;
                } else {  // 戴口罩
                    new_time = time + 2;
                    int adjacent_infected = 0;
                    for (auto [dr2, dc2] : directions) {
                        int ar = nr + dr2;
                        int ac = nc + dc2;
                        if (0 <= ar && ar < row_n && 0 <= ac && ac < column_m && infected_time[ar][ac] == time) {
                            adjacent_infected += 1;
                        }
                    }
                    if (adjacent_infected >= 2) {
                        new_time = std::min(new_time, time + 1);
                    }
                }

4.更新: 

此时对当前的时间与当前位置原本的时间(或未感染)进行 比较:

        当小于时,便需要将原本写入的时间更新为此时更短实现感染完成的时间,同时插入到队列中,进行下一轮循环

            if (new_time < infected_time[nr][nc]) {
                    infected_time[nr][nc] = new_time;
                    queue.push({nr, nc, new_time});
                }

 5.返回

也就是遍历,一旦发现有未感染的则返回-1说明无法达成题目要求 

    int max_time = 0;
    for (int r = 0; r < row_n; ++r) {
        for (int c = 0; c < column_m; ++c) {
            if (infected_time[r][c] == std::numeric_limits<int>::max()) {
                return -1;  // 表示有些人无法感染
            }
            max_time = std::max(max_time, infected_time[r][c]);
        }
    }

 最终的实现代码如下:

#include <iostream>
#include <vector>
#include <queue>
#include <utility>
#include <limits>

int solution(int row_n, int column_m, std::vector<std::vector<int>> seats, std::vector<int> patient) {
    std::vector<std::pair<int, int>> directions = {
  
  {0, 1}, {1, 0}, {0, -1}, {-1, 0}};
    std::queue<std::tuple<int, int, int>> queue;
    std::vector<std::vector<int>> infected_time(row_n, std::vector<int>(column_m, std::numeric_limits<int>::max()));

    int start_row = patient[0];
    int start_col = patient[1];
    queue.push({start_row, start_col, 0});  // (行, 列, 时间)
    infected_time[start_row][start_col] = 0;

    while (!queue.empty()) {
        auto [r, c, time] = queue.front();
        queue.pop();

        for (auto [dr, dc] : directions) {
            int nr = r + dr;
            int nc = c + dc;

            if (0 <= nr && nr < row_n && 0 <= nc && nc < column_m) {
                int new_time;
                if (seats[nr][nc] == 0) {  // 未戴口罩
                    new_time = time + 1;
                } else {  // 戴口罩
                    new_time = time + 2;
                    int adjacent_infected = 0;
                    for (auto [dr2, dc2] : directions) {
                        int ar = nr + dr2;
                        int ac = nc + dc2;
                        if (0 <= ar && ar < row_n && 0 <= ac && ac < column_m && infected_time[ar][ac] == time) {
                            adjacent_infected += 1;
                        }
                    }
                    if (adjacent_infected >= 2) {
                        new_time = std::min(new_time, time + 1);
                    }
                }
                if (new_time < infected_time[nr][nc]) {
                    infected_time[nr][nc] = new_time;
                    queue.push({nr, nc, new_time});
                }
            }
        }
    }

    int max_time = 0;
    for (int r = 0; r < row_n; ++r) {
        for (int c = 0; c < column_m; ++c) {
            if (infected_time[r][c] == std::numeric_limits<int>::max()) {
                return -1;  // 表示有些人无法感染
            }
            max_time = std::max(max_time, infected_time[r][c]);
        }
    }

    return max_time;
}


int main() {
    // 你可以添加更多测试用例
    std::vector<std::vector<int>> testSeats1 = {
  
  {0,1,1,1},{1,0,1,0},{1,1,1,1},{0,0,0,1}};
    std::vector<std::vector<int>> testSeats2 = {
  
  {0,1,1,1},{1,0,1,0},{1,1,1,1},{0,0,0,1}};
    std::vector<std::vector<int>> testSeats3 = {
  
  {0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0}};
    std::vector<std::vector<int>> testSeats4 = {
  
  {1,1,1,1},{1,1,1,1},{1,1,1,1},{1,1,1,1}};
    std::vector<std::vector<int>> testSeats5 = {
  
  {1}};

    std::cout << (solution(4, 4, testSeats1, {2, 2}) == 6) << std::endl;
    std::cout << (solution(4, 4, testSeats2, {2, 5}) == 0) << std::endl;
    std::cout << (solution(4, 4, testSeats3, {2, 2}) == 4) << std::endl;
    std::cout << (solution(4, 4, testSeats4, {2, 2}) == 6) << std::endl;
    std::cout << (solution(1, 1, testSeats5, {0, 0}) == 0) << std::endl;

    return 0;
}

运行结果: 

 

 

 

 

 

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

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

相关文章

SQL表间关联查询详解

简介 本文主要讲解SQL语句中常用的表间关联查询方式&#xff0c;包括&#xff1a;左连接&#xff08;left join&#xff09;、右连接&#xff08;right join&#xff09;、全连接&#xff08;full join&#xff09;、内连接&#xff08;inner join&#xff09;、交叉连接&…

路由器旁挂三层网络实现SDWAN互联(爱快SD-WAN)

近期因公司新办公区建设&#xff0c;原有的爱快路由器的SDWAN功能实现分支之间互联的服务还需要继续使用。在原有的小型网络中&#xff0c;使用的爱快路由器当作网关设备&#xff0c;所以使用较为简单,如下图所示。 现变更网络拓扑为三层网络架构&#xff0c;但原有的SDWAN分支…

麦田物语学习笔记:制作[SceneName]Attribute特性

基本流程 因为在现有的项目中,像开始场景的切换或者Telepot组件都需要手动输入场景名,有时还可能键入出错,而该特性能用选择的方式去解决这一问题 1.代码实现 SceneNameDrawer.cs //参数绘制 using UnityEditor; using UnityEngine; #if UNITY_EDITOR [CustomPropertyDrawer(…

HTML之拜年/跨年APP(改进版)

目录&#xff1a; 一&#xff1a;目录 二&#xff1a;效果 三&#xff1a;页面分析/开发逻辑 1.页面详细分析&#xff1a; 2.开发逻辑&#xff1a; 四&#xff1a;完整代码&#xff08;不多废话&#xff09; index.html部分 app.json部分 二&#xff1a;效果 三&#xff1a;页面…

【2024 年度总结】从小白慢慢成长

【2024 年度总结】从小白慢慢成长 1. 加入 CSDN 的契机2. 学习过程2.1 万事开头难2.2 下定决心开始学习2.3 融入技术圈2.4 完成万粉的目标 3. 经验分享3.1 工具的选择3.2 如何提升文章质量3.3 学会善用 AI 工具 4. 保持初心&#xff0c;继续前行 1. 加入 CSDN 的契机 首次接触…

一文大白话讲清楚webpack基本使用——2——css相关loader的配置和使用

一文大白话讲清楚webpack基本使用——2——css相关loader的配置和使用 1. 建议按文章顺序从头看是看 第一篇&#xff1a;一文大白话讲清楚啥是个webpack第二篇&#xff1a;一文大白话讲清楚webpack基本使用——1——完成webpack的初步构建然后看本篇&#xff0c;Loader的配置…

如何将 session 共享存储到 redis 中

文章目录 一. 分布式 session 登录1.1 什么是分布式&#xff1f;1.2 Session 共享1.3 为什么服务器 A 登录后&#xff0c;请求发到服务器 B&#xff0c;不认识该用户&#xff1f;1.4 共享存储 二. Session 共享实现Redis三. 测试session共享四. cookie设置4.1 前端4.2 后端 一.…

Debezium日常分享系列之:对于从Oracle数据库进行快照的性能优化

Debezium日常分享系列之&#xff1a;对于从Oracle数据库进行快照的性能优化 源数据库Kafka Connect监控测试结果 源数据库 Oracle 19c&#xff0c;本地&#xff0c;CDB数据库主机的I/O带宽为6 GB/s&#xff0c;由此主机上运行的所有数据库共享临时表空间由42个文件组成&#x…

STM32 FreeROTS Tickless低功耗模式

低功耗模式简介 FreeRTOS 的 Tickless 模式是一种特殊的运行模式&#xff0c;用于最小化系统的时钟中断频率&#xff0c;以降低功耗。在 Tickless 模式下&#xff0c;系统只在有需要时才会启动时钟中断&#xff0c;而在无任务要运行时则完全进入休眠状态&#xff0c;从而降低功…

Redis - General - 未授权访问漏洞(用户配置问题)

0x01&#xff1a;产品简介 Redis&#xff08;Remote Dictionary Service&#xff0c;远程数据服务&#xff09;&#xff0c;是一款开源的基于内存的键值对存储系统&#xff0c;其主要被用作高性能缓存服务器使用&#xff08;比如作为消息中间件和用于 Session 共享&#xff09…

学习threejs,使用OrbitControls相机控制器

&#x1f468;‍⚕️ 主页&#xff1a; gis分享者 &#x1f468;‍⚕️ 感谢各位大佬 点赞&#x1f44d; 收藏⭐ 留言&#x1f4dd; 加关注✅! &#x1f468;‍⚕️ 收录于专栏&#xff1a;threejs gis工程师 文章目录 一、&#x1f340;前言1.1 ☘️THREE.OrbitControls 相机控…

SQL和MySQL以及DAX的日期表生成?数字型日期?将生成的日期表插入到临时表或者实体表中

几种生成日期表的方法 如何用SQL语句生成日期表呢&#xff1f; 如何用MySQL语句生成日期表呢&#xff1f; 如何用DAX语句生成日期表呢&#xff1f; 1. MySQL生成日期表 1.1 日期格式&#xff1a;yyyy-MM-dd 字符型 2024-01-02 -- 生成日期表 WITH RECURSIVE temp_dateTable …

C# 动态创建Label和ComboBox控件并修改Text

背景&#xff1a;在做项目的时候可能需要根据一定数量创建某些控件并修改其属性&#xff0c;本文以控件label、ConboBox控件进行动态创建。 程序运行前后的的Form动态图 代码如下&#xff1a; using System; using System.Collections.Generic; using System.ComponentModel; …

2025年编程语言热度分析:Python领跑,Go与Rust崛起

TIOBE Index&#xff08;TIOBE 编程语言指数&#xff09;是一个衡量编程语言流行度的排名系统。它通过分析多种搜索引擎、在线编程社区、技术论坛、问答网站&#xff08;如 Google、Bing、Yahoo、Wikipedia、Stack Overflow&#xff09;等的搜索和讨论数据&#xff0c;评估不同…

【从零开始入门unity游戏开发之——C#篇46】C#补充知识点——命名参数和可选参数

考虑到每个人基础可能不一样&#xff0c;且并不是所有人都有同时做2D、3D开发的需求&#xff0c;所以我把 【零基础入门unity游戏开发】 分为成了C#篇、unity通用篇、unity3D篇、unity2D篇。 【C#篇】&#xff1a;主要讲解C#的基础语法&#xff0c;包括变量、数据类型、运算符、…

python学opencv|读取图像(三十九 )阈值处理Otsu方法

【1】引言 前序学习了5种阈值处理方法&#xff0c;包括(反)阈值处理、(反)零值处理和截断处理&#xff0c;还学习了一种自适应处理方法&#xff0c;相关文章链接为&#xff1a; python学opencv|读取图像&#xff08;三十三&#xff09;阈值处理-灰度图像-CSDN博客 python学o…

【Idea】编译Spring源码 read timeout 问题

Idea现在是大家工作中用的比较多的开发工具&#xff0c;尤其是做java开发的&#xff0c;那么做java开发&#xff0c;了解spring框架源码是提高自己技能水平的一个方式&#xff0c;所以会从spring 官网下载源码&#xff0c;导入到 Idea 工具并编译&#xff0c;但是发现build的时…

macOS安装Gradle环境

文章目录 说明安装JDK安装Gradle 说明 gradle8.5最高支持jdk21&#xff0c;如果使用jdk22建议使用gradle8.8以上版本 安装JDK mac系统安装最新&#xff08;截止2024.9.13&#xff09;Oracle JDK操作记录 安装Gradle 下载Gradle&#xff0c;解压将其存放到资源java/env目录…

VMware Workstation Pro 17免费开放,再也不用到处找license了

VMware Workstation Pro 17免费开放啦 VMware Workstation Pro 17.6.2 版本介绍一、免费开放二、性能与稳定性提升三、重要问题修复1. Linux 快照崩溃问题解决2. Windows 11 主机优化3. Linux 内核兼容性增强 四、功能亮点1. 全新的性能优化2. 稳定性和可靠性增强3. 更友好的用…

寒假1.19

题解 web&#xff08;堆叠注入&#xff09;&#xff1a;[SUCTF 2019]EasySQL 参考wp&#xff1a;BUUCTF [SUCTF 2019]EasySQL1 writeup(详细版&#xff09;-CSDN博客 判断&#xff1a; 法一&#xff1a; 打开环境&#xff0c;有一个可交互的界面&#xff0c;随便输入几个字…