病毒感染时间(字节青训营)

复制代码
# 问题描述

在一个封闭的房间里摆满了座位,每个座位东西向和南北向都有固定 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
  • 二维布尔数组 :利用一个二维布尔数组存储房间内人员口罩情况(行,列),若带口罩为 true,不戴为 false。

  • 感染情况记录 :再用一个二维布尔数组记录感染情况,感染为 true,根据 (x, y) 初始化感染人员位置。

  • 坐标变化定义 :定义上下左右的方法坐标变化,类似于(向左:x-1,y,向下:x,y-1)。

  • 时间初始化 :定义一个总时间 time = 0。

  • bfs 函数定义:

    • 若查询口罩情况为戴口罩,标记为不戴口罩,然后退出函数。
    • 查询感染情况,若没有感染,标记为已经感染,将这个位置加入 temp 队列,然后退出函数。
  • 主函数逻辑:

    • 用一个键值对队列记录总已经感染的位置。
    • while 循环(直到队列长度等于 m*n 总座位的数量):
      • 用 temp 队列(记录单次新增感染座位坐标),对于队列中所有感染的位置上下左右调用 bfs 函数。
      • 当次循环结束前 time += 1,temp 队列元素加入总队列中。
      • 增加新位置的溢出判断和首位感染者位置是否合法的判断(若不合法,直接输出 0)。
java 复制代码
import java.util.LinkedList;
import java.util.Queue;

public class Main {
    static int[][] seats; // 存储口罩情况
    static boolean[][] infectionStatus; // 二维布尔数组存储感染情况
    static int[] dx = { -1, 1, 0, 0 }; // 左右下上的 x 坐标变化
    static int[] dy = { 0, 0, -1, 1 }; // 左右下上的 y 坐标变化

    public static void bfs(int x, int y, Queue<int[]> temp) {
        if (x < 0 || x >= seats.length || y < 0 || y >= seats[0].length) {
            return; // 新位置溢出判断
        }

        if (seats[x][y] == 1) {
            seats[x][y] = 0;
            return; // 如果有口罩,直接返回
        }
        if (!infectionStatus[x][y]) {
            infectionStatus[x][y] = true; // 标记为感染
            temp.offer(new int[] { x, y }); // 添加到临时队列
        }
    }

    public static int solution(int row_n, int column_m, int[][] seats, int[] patient) {
        if (patient[0] < 0 || patient[0] >= row_n || patient[1] < 0 || patient[1] >= column_m) {
            return 0; // 首位感染者位置不合法判断
        }
        Main.seats = seats;
        infectionStatus = new boolean[row_n][column_m];
        int x = patient[0];
        int y = patient[1];
        infectionStatus[x][y] = true;

        Queue<int[]> totalInfected = new LinkedList<>();
        totalInfected.offer(new int[] { x, y }); // 添加到临时队列
        Queue<int[]> temp = new LinkedList<>();
        int time = 0;

        while (totalInfected.size() < row_n * column_m) {
            // System.out.println("时间: " + time + ", 当前总感染位置数: " + totalInfected.size()); //
            // 调试打印
            for (int[] position : totalInfected) {
                int curX = position[0];
                int curY = position[1];
                for (int i = 0; i < 4; i++) {
                    int newX = curX + dx[i];
                    int newY = curY + dy[i];
                    if (newX >= 0 && newX < row_n && newY >= 0 && newY < column_m) {
                        bfs(newX, newY, temp);
                    }
                }
            }
            time++;
            totalInfected.addAll(temp);
            // System.out.println("本轮新增感染位置: " + temp.size()); // 调试打印
            temp.clear();
        }
        return time;
    }

    public static void main(String[] args) {
        // You can add more test cases here
        int[][] testSeats1 = { { 0, 1, 1, 1 }, { 1, 0, 1, 0 }, { 1, 1, 1, 1 }, { 0, 0, 0, 1 } };
        int[][] testSeats2 = { { 0, 1, 1, 1 }, { 1, 0, 1, 0 }, { 1, 1, 1, 1 }, { 0, 0, 0, 1 } };
        int[][] testSeats3 = { { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 } };
        int[][] testSeats4 = { { 1, 1, 1, 1 }, { 1, 1, 1, 1 }, { 1, 1, 1, 1 }, { 1, 1, 1, 1 } };
        int[][] testSeats5 = { { 1 } };

        System.out.println(solution(4, 4, testSeats1, new int[] { 2, 2 }) == 6);
        System.out.println(solution(4, 4, testSeats2, new int[] { 2, 5 }) == 0);
        System.out.println(solution(4, 4, testSeats3, new int[] { 2, 2 }) == 4);
        System.out.println(solution(4, 4, testSeats4, new int[] { 2, 2 }) == 6);
        System.out.println(solution(1, 1, testSeats5, new int[] { 0, 0 }) == 0);
    }
}
相关推荐
yi0117 分钟前
DAY17: LeetCode 139|单词拆分:从“把单词删掉”到用 DP 记录合法切口
人工智能·笔记·python·算法·leetcode·动态规划
马剑威(威哥爱编程)10 分钟前
【AI全栈后端12-03】Spring Boot 用多模型路由把智能客服成本降下来
java·人工智能·spring boot
霸道流氓气质14 分钟前
AI模型幻觉检测与抑制完全指南:从规则引擎到RAG对比的Java生产级实战
java·开发语言·人工智能
陈希瑞19 分钟前
LongCat-2.5-Preview 的web逆向能力实测
人工智能·算法·wasm
niucloud-admin25 分钟前
JAVA V6 多商户商城 开发文档——手机端前端
java·开发语言·前端
云安全助手30 分钟前
自建接入VS聚合平台:企业 AI 调用的选型思路与迁移成本拆解
java·大数据·数据库·人工智能·ai大模型
樱花落木兰31 分钟前
SpringBoot + ECharts 后台数据统计报表模块实战
java·javascript·spring boot·ai·log4j·github·echarts
霸道流氓气质40 分钟前
Dify 可视化 LLM 应用开发平台完全指南:从Workflow编排到Java生产级集成实战
java·开发语言
m0_5873830044 分钟前
24小时自助健身房软硬件解决方案实战:从架构设计到部署指南
java·spring·小程序·架构·需求分析
CallFay云起未来1 小时前
AI客服上线后多久才能回本?从TCO到ROI的完整测算方法
java·大数据·人工智能·架构·文心一言