首页 > 其他分享 >AI刷题-病毒在封闭空间中的传播时间

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

时间:2025-01-20 23:56:41浏览次数:3  
标签:std 口罩 AI 感染 封闭 int infected time 刷题

目录

问题描述

输入格式

输出格式

解题思路:

问题理解

数据结构选择

算法步骤

代码实现: 

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;
}

运行结果: 

 

 

 

 

 

标签:std,口罩,AI,感染,封闭,int,infected,time,刷题
From: https://blog.csdn.net/m0_73302939/article/details/145270742

相关文章

  • springboot703招生管理系统(论文+源码)_kaic
     摘要在Internet高速发展的今天,我们生活的各个领域都涉及到计算机的应用,其中包括招生管理系统的网络应用,在外国招生管理系统已经是很普遍的方式,不过国内的管理网站可能还处于起步阶段。招生管理系统具有招生公告信息管理功能的选择。招生管理系统采用java技术,基于springboo......
  • springboot707智慧外贸平台(论文+源码)_kaic
     摘 要网络的广泛应用给生活带来了十分的便利。所以把智慧外贸管理与现在网络相结合,利用java技术建设智慧外贸平台,实现智慧外贸的信息化。则对于进一步提高智慧外贸管理发展,丰富智慧外贸管理经验能起到不少的促进作用。智慧外贸平台能够通过互联网得到广泛的、全面的宣传......
  • springboot701广场舞团(论文+源码)_kaic
     摘要随着信息技术和网络技术的飞速发展,人类已进入全新信息化时代,传统管理技术已无法高效,便捷地管理信息。为了迎合时代需求,优化管理效率,各种各样的管理系统应运而生,各行各业相继进入信息管理时代,广场舞团就是信息时代变革中的产物之一。任何系统都要遵循系统设计的基本流......
  • Mimikyu靶场刷题记录
     目录靶场地址: 综合漏洞练习靶场-极核::CTFPass01SourcePass02ResponsePass03GetPass04RobotsPass05BackupPass06CookiePass07HTML整体结构元数据部分页面内容关于 disabled 属性pass08xff_refererpass09PHP一、代码功能概述二、代码逐行分析p......
  • 【刷题实录之二叉树】leecode429. N 叉树的层序遍历(层序遍历)
    题目:给定一个N叉树,返回其节点值的层序遍历。(即从左到右,逐层遍历)。树的序列化输入是用层序遍历,每组子节点都由null值分隔。题解:本体是层序遍历的变形,只需要将“左右孩子入队”变成“所有孩子入队”即可,需对结点数据结构有深入把握。代码(C++):classSolution{public:......
  • 如何在LangChain中缓存模型响应
    在开发涉及语言模型(LLM)的应用程序时,缓存模型响应可以显著提升性能和降低成本。通过这一技术指南,我们将深入探讨如何在LangChain中实现响应的缓存,确保在不影响系统表现的情况下有效利用计算资源。技术背景介绍在很多情况下,特别是对相同输入多次调用模型时,直接缓存先前的......
  • AI 在生活中的渗透与技术解析
    引言在当今数字化时代,人工智能(AI)已不再是科幻小说中的概念,而是实实在在地渗透到人们生活的方方面面。从清晨醒来使用的智能语音助手,到夜晚入睡时智能家居设备营造的舒适环境,AI技术正悄然改变着我们的生活方式、工作模式以及社会互动。本文旨在深入探讨AI在生活中的具体应用......
  • golang 多线程 备份文件夹到兄弟层级 wail group
    golang多线程备份文件夹到兄弟层级wailgroupD:\GolangTools\src\config\config.gopackageconfigtypeConfigHandlerstruct{ includeDirNames[]string includeFileNames[]string excludeDirNames[]string excludeFileNames[]string}funcNewConfigHandler......
  • 给初学者的人工智能(AI)入门教程
    ......
  • AI与药学 | Med-Pal:轻量级大型语言模型在药物咨询领域的应用
    随着新冠疫情的催化,数字医疗正以前所未有的速度发展,传统的面对面医疗服务模式逐渐向线上转移。数字健康工具的普及提升了患者的健康素养,也为医护人员带来了更沉重的文书工作和认知负担。大型语言模型(LLMs)的出现,为解决这一矛盾提供了新的可能。LLMs在经过优化后,有望成为总......