跳到主要内容
极客日志极客日志面向AI+效率的开发者社区
首页博客GitHub 精选镜像工具UI配色美学隐私政策关于联系
搜索内容 / 工具 / 仓库 / 镜像...⌘K搜索
注册
博客列表
Javajava算法

Java 实现的网格疫情扩散模拟算法

综述由AI生成针对 3x3 网格中疫情随时间向四周扩散的问题,提供了一套完整的 Java 解决方案。利用广度优先搜索(BFS)算法模拟每一时间步的传播过程,通过队列管理当前感染源,计算达到全图感染所需的最小步数。代码结构清晰,封装了坐标操作类以处理边界条件,避免了硬编码判断。该算法适用于小规模网格仿真,时间复杂度可控,是理解多源 BFS 应用的典型案例。

技术博主发布于 2021/3/7更新于 2026/6/622 浏览
Java 实现的网格疫情扩散模拟算法

这是一个经典的网格模拟问题。给定一个 3x3 的地图,用二进制字符串表示,1 代表有疫情,0 代表没有。规则很简单:每隔一个时间步,有疫情的网格会向它上下左右四个相邻网格进行扩散。我们的目标是计算多少个时间步以后整个地图都有疫情。

解决这类传播问题的核心思路是广度优先搜索(BFS)。因为每一轮扩散都是同步发生的,BFS 天然适合按层遍历,每一层就对应一个时间步。我们不需要递归,只需要维护一个队列来存储当前所有被感染的坐标点。

在实现细节上,为了代码的可读性,我封装了一个 Point 类来处理坐标转换和边界检查。这里有个小坑要注意:二维数组转一维索引时,行和列的计算不能搞混。下面的代码中,sideLength 设为 3,index 除以 sideLength 得到行号,余数得到列号。邻居节点的判断必须严格限制在 0 到 sideLength-1 之间,防止越界。

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.Queue;
import java.util.Scanner;

class Point {
    int x = -1;
    int y = -1;
    int sideLength;

    Point(int index, int sideLength) {
        this.sideLength = sideLength;
        // 修正逻辑:x 为行,y 为列
        this.x = index / sideLength;
        this.y = index % sideLength;
    }

    // 获取上方邻居索引
    int top() {
        return x > 0 ? (x - 1) * sideLength + y : -1;
    }

    // 获取下方邻居索引
    int bottom() {
        return x < sideLength - 1 ? (x + 1) * sideLength + y : -1;
    }

    // 获取左方邻居索引
    int left() {
        return y > 0 ? x * sideLength + y - 1 : -1;
    }

    // 获取右方邻居索引
    int right() {
        return y < sideLength - 1 ? x * sideLength + y + 1 : -1;
    }
}

public class EpidemicSpread {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        String mapStr = scanner.next();
        int sideLength = 3;
        int totalCells = sideLength * sideLength;
        boolean[] infected = new boolean[totalCells];
        Queue<Integer> queue = new LinkedList<>();

        // 初始化初始感染状态
        for (int i = 0; i < totalCells; i++) {
            if (mapStr.charAt(i) == '1') {
                infected[i] = true;
                queue.offer(i);
            }
        }

        int steps = 0;
        while (!queue.isEmpty()) {
            int size = queue.size();
            boolean spreadHappened = false;
            
            // 处理当前时间步的所有感染源
            for (int i = 0; i < size; i++) {
                int currentIdx = queue.poll();
                Point p = new Point(currentIdx, sideLength);
                
                int[] neighbors = {p.top(), p.bottom(), p.left(), p.right()};
                for (int neighbor : neighbors) {
                    if (neighbor != -1 && !infected[neighbor]) {
                        infected[neighbor] = true;
                        queue.offer(neighbor);
                        spreadHappened = true;
                    }
                }
            }
            
            // 如果这一轮没有新感染,且还有未感染区域,说明无法扩散完全
            if (!spreadHappened) {
                break;
            }
            steps++;
        }

        // 检查是否全部感染
        boolean allInfected = true;
        for (boolean b : infected) {
            if (!b) {
                allInfected = false;
                break;
            }
        }
        
        System.out.println(allInfected ? steps : -1);
    }
}

这段代码里最关键的逻辑在于 while 循环内部。我们使用 size 变量来锁定当前层的节点数量,确保每一轮只处理同一时间步产生的影响。每次从队列取出一个点,计算它的四个合法邻居,如果邻居未被感染,就标记并加入队列。这样自然形成了层级推进的效果。

实际运行时会遇到一种情况:初始地图全为 0,或者某些区域被 0 隔断导致永远无法感染。代码最后做了一个全图检查,如果存在未感染单元格,返回 -1 表示无解。对于 3x3 这种小规模数据,这个方案效率很高,空间占用也极小。如果是更大的网格,可以考虑使用位运算优化状态存储,但逻辑框架是一样的。

  • 💰 8折买阿里云服务器限时8折了解详情
  • Magick API 一键接入全球大模型注册送1000万token查看
  • 🤖 一键搭建Deepseek满血版了解详情
  • 一键打造专属AI 智能体了解详情
极客日志微信公众号二维码

微信扫一扫,关注极客日志

微信公众号「极客日志V2」,在微信中扫描左侧二维码关注。展示文案:极客日志V2 zeeklog

更多推荐文章

查看全部
  • 文心一言 4.5 评测与本地部署指南:开源大模型的中文能力实测
  • LLaMA-Factory 数据集制作与 Qwen3 模型微调评估
  • P1203 [IOI 1993 / USACO1.1] 坏掉的项链 Broken Necklace Python 题解
  • C++与Rust数据交互与内存安全传递技术
  • 高版本 Python pyc 文件反编译失败与残缺问题的 AI 辅助解决方案
  • 零基础转行 Python 工程师:我的学习路径与实战经验总结
  • Java 核心语法与并发编程实战示例
  • SpringBoot 国际化 i18n 实战:配置文件与动态切换方案
  • C++ 关联式容器:map 与 set 详解
  • 大模型混战时代互联网企业的转型与应对策略
  • 时序数据库选型指南:Apache IoTDB 核心优势与评估维度
  • 本周 GitHub 爆火!10 个开源神器,彻底改变你的 AI 开发效率
  • Python 非官方 Google 搜索 API 使用指南
  • AI 安全实战:基于 Stable Diffusion 的视觉提示词注入攻击研究
  • Superpowers:用工程流程纪律驯化 Claude Code 实现可靠交付
  • 基于混元 AIGC 与腾讯云智能体的文思通智能写作助手构建
  • Python 和 PyCharm 安装配置教程
  • AI 辅助撰写学术论文综述的方法与实践指南
  • 二分查找实战:山脉数组的峰顶索引与寻找峰值
  • 中国人工智能大模型技术白皮书核心内容解读

相关免费在线工具

  • Keycode 信息

    查找任何按下的键的javascript键代码、代码、位置和修饰符。 在线工具,Keycode 信息在线工具,online

  • Escape 与 Native 编解码

    JavaScript 字符串转义/反转义;Java 风格 \uXXXX(Native2Ascii)编码与解码。 在线工具,Escape 与 Native 编解码在线工具,online

  • JavaScript / HTML 格式化

    使用 Prettier 在浏览器内格式化 JavaScript 或 HTML 片段。 在线工具,JavaScript / HTML 格式化在线工具,online

  • JavaScript 压缩与混淆

    Terser 压缩、变量名混淆,或 javascript-obfuscator 高强度混淆(体积会增大)。 在线工具,JavaScript 压缩与混淆在线工具,online

  • 加密/解密文本

    使用加密算法(如AES、TripleDES、Rabbit或RC4)加密和解密文本明文。 在线工具,加密/解密文本在线工具,online

  • Gemini 图片去水印

    基于开源反向 Alpha 混合算法去除 Gemini/Nano Banana 图片水印,支持批量处理与下载。 在线工具,Gemini 图片去水印在线工具,online