news 2026/6/30 15:55:46

从二维数组到广搜:流感传染问题的算法优化实战

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
从二维数组到广搜:流感传染问题的算法优化实战

1. 流感传染问题:从暴力模拟到智能优化

第一次接触流感传染问题时,我像大多数初学者一样,本能地想到用二维数组暴力模拟。题目描述很简单:在一个n×n的房间矩阵中,'@'代表病人,'.'代表健康人,每天病人会传染相邻的健康人,问m天后共有多少人患病。最直观的解法就是开两个数组,每天遍历整个矩阵检查每个健康人周围是否有病人,这种解法时间复杂度O(mn²),当n=100,m=100时需要百万次运算。

但当我用这种方法提交到OpenJudge系统时,虽然通过了测试,但执行时间明显比排行榜前列的代码慢。这促使我开始思考优化方案。仔细分析传染过程会发现,已经患病多天的人其实不会产生新的传染——只有前一天刚被感染的人才会在当天传染他人。这个发现让我联想到广度优先搜索(BFS)的层序遍历特性,于是尝试用队列优化,将时间复杂度直接降到O(n²),运算次数降至万次级别。

2. 二维数组模拟法的实现细节

2.1 基础实现思路

二维数组解法需要维护两个数组:原数组mp和临时数组t。每天开始时清空临时数组,然后遍历每个房间:

  • 如果是病人('@'),直接复制到临时数组
  • 如果是健康人('.'),检查四个方向的邻居
  • 发现邻居有病人就将当前房间标记为患病
  • 最后将临时数组拷贝回原数组
for(int k=2; k<=m; k++) { // 第k天 memset(t, 0, sizeof(t)); for(int i=1; i<=n; i++) for(int j=1; j<=n; j++) { t[i][j] = mp[i][j]; if(mp[i][j] == '.') { for(int l=0; l<4; l++) { // 检查四个方向 int x = i + dir[l][0], y = j + dir[l][1]; if(x>=1 && x<=n && y>=1 && y<=n && mp[x][y]=='@') t[i][j] = '@'; } } } memcpy(mp, t, sizeof(t)); }

2.2 性能瓶颈分析

虽然这个解法直观易懂,但存在明显性能问题。假设矩阵中有k个病人,每天都要完整扫描n²个房间,其中很多是已经不会产生传染的"老病人"。就像在疫情追踪时,如果每天都重新排查所有历史病例,效率肯定低下。实际只需要关注新出现的感染者即可。

3. 广度优先搜索的优化之道

3.1 BFS解法核心思想

BFS解法的精妙之处在于用队列实现了"增量更新"。初始时将所有病人入队,记录他们是在第1天被感染。然后循环处理队列:

  1. 出队一个病人u
  2. 如果u是在第m天被感染,则不再传播
  3. 否则检查u的四个邻居
  4. 将新感染的邻居入队,记录感染天数为u.d+1
struct Node { int x,y,d; }; // 坐标和感染天数 queue<Node> que; while(!que.empty()) { Node u = que.front(); que.pop(); ct++; // 统计病人数 if(u.d == m) continue; // 不传播 for(int i=0; i<4; i++) { int x=u.x+dir[i][0], y=u.y+dir[i][1]; if(x>=1 && x<=n && y>=1 && y<=n && !vis[x][y] && mp[x][y]=='.') { mp[x][y] = '@'; que.push(Node{x,y,u.d+1}); } } }

3.2 为什么BFS更高效

BFS的高效性体现在两个方面:一是避免了重复检查,每个病人只处理一次;二是传播过程具有方向性,从早到晚按天数顺序处理。这就像疫情防控中,我们只需要追踪密接者,而不需要每天重新筛查全体人群。在n=100的案例中,BFS将运算量从百万级降到万级,效率提升两个数量级。

4. 两种解法的对比与选型

4.1 时间复杂度对比

指标二维数组法BFS优化法
时间复杂度O(mn²)O(n²)
100×100案例≈1,000,000≈10,000
适用场景m较小m较大

4.2 实际编码建议

对于信息学竞赛选手,我的建议是:

  1. 初次解题可以用二维数组法保底,确保正确性
  2. 对大数据量案例,必须掌握BFS优化
  3. 注意边界条件处理,如房间越界检查
  4. 使用结构体封装节点信息,提高代码可读性

在NOI等竞赛中,类似的优化思路可以推广到网格类问题,比如火灾蔓延、病毒传播等场景。理解BFS的时间复杂度优势,能帮助我们在解题时快速判断算法可行性。

5. 从具体问题到算法思维

这个案例生动展示了算法优化如何大幅提升程序效率。二维数组解法就像用蛮力解决问题,而BFS解法则像找到了问题的内在规律。在实际开发中,我经常遇到类似情况:初始方案能work但性能不佳,通过分析问题本质找到优化突破口。

建议初学者多思考:当前解法是否做了不必要的计算?数据变化是否有规律可循?用空间换时间是否值得?这种思维训练比单纯AC题目更重要。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/30 15:55:23

GB/T 41866.2-2022《系统与软件工程 信息技术项目绩效基准度量框架 第 2 部分:基准度量要求》标准解读

结合GB/T 41866 系列标准体系&#xff0c;本文承接第 1 部分概念定义内容&#xff0c;系统解读第2 部分基准度量要求&#xff0c;明确该标准的定位、适用范围、三层过程模型、七大核心活动及配套框架&#xff0c;为IT 项目管理人员、软件造价评估人员、第三方咨询机构、项目实施…

作者头像 李华
网站建设 2026/6/30 15:54:17

计算机毕业设计之基于人脸识别的校园快递取件系统

本项目致力于开发一款基于人脸识别的校园快递取件系统&#xff0c;以提升校园快递服务的效率与便捷性。系统采用Java语言作为后端开发基础&#xff0c;结合SpringBoot框架&#xff0c;实现了高效、稳定的后端服务。前端则采用Vue框架&#xff0c;为用户提供了直观、友好的交互界…

作者头像 李华
网站建设 2026/6/30 15:49:58

Prompt Learning 如何革新NLP?从“完形填空”到高效调优的演进之路

1. 从传统微调到Prompt Learning的范式转变 记得我第一次接触NLP任务时&#xff0c;导师扔给我一个情感分析数据集&#xff0c;要求用BERT模型实现分类。当时我按照教程&#xff0c;在BERT后面接了个全连接层&#xff0c;然后开始了漫长的微调过程。结果训练了三天三夜&#x…

作者头像 李华
网站建设 2026/6/30 15:48:58

TimescaleDB压缩算法实现

压缩功能完全不需要 PG 内核修改 TimescaleDB 的压缩和列存功能是 纯 PostgreSQL 扩展实现&#xff0c;不需要任何 PG 内核补丁。可以在原生的 PostgreSQL 14/15/16/17 上直接安装使用。 一、压缩功能如何独立实现&#xff1f; 1. 自定义数据类型 — 标准 CREATE TYPE 压缩后…

作者头像 李华