当前位置: 首页 > news >正文

第3章 模拟法

3.1 模拟法概述

模拟法设计思想
模拟法通过将现实问题抽象成计算机可识别的符号与操作,按逻辑顺序“模拟”其过程,从而得到结果;它不依赖复杂公式或高深技巧,只需理清问题背景与实现步骤即可。

示例:鸡兔同笼问题

题目
笼中有若干鸡和兔,鸡有 2 只脚,兔有 4 只脚。给定脚的总数 n,求笼中动物数的最大值与最小值。

思路

  • 当所有动物都假设为鸡时,数量最大;

  • 当尽量多假设为兔时,数量最小;

  • 分别根据 n 的奇偶性以及能否被 4 整除进行处理。

伪代码

函数 Feets(n, maxNum, minNum):如果 n % 2 ≠ 0:maxNum = 0minNum = 0否则如果 n % 4 == 0:maxNum = n / 2minNum = n / 4否则:maxNum = n / 2minNum = (n - 2) / 4 + 1返回 maxNum, minNum


3.2 数学问题中的模拟法

3.2.1 约瑟夫环问题

题目
n 个人围成一圈,从 1 开始报数,报到 m 的人出列,下一次从下一个人继续,直至所有人出列;求出列顺序或最后剩余的编号。

思路

  1. 用数组 removed[0…n-1] 记录某人是否已出列;

  2. 利用 i = (i + 1) % n 实现环形遍历;

  3. 每次计数到 m 且该位置未出列时,标记出列并继续。

伪代码

函数 Josephus(n, m):removed = [0] * ncount = 0, i = -1, numOut = 0当 numOut < n - 1:count = 0当 count < m:i = (i + 1) % n如果 removed[i] == 0:count += 1removed[i] = 1numOut += 1返回 所有 removed[i] == 0 的 i + 1 列表

3.2.2 埃拉托色尼筛法

题目
求区间 [1, n] 内所有素数。

思路

  1. 假设所有数初始为素数;

  2. 从 2 开始,将其倍数标记为合数;

  3. 剩余未标记的即为素数。

伪代码

函数 EratoSieve(n):A[1…n] 全设为 0  (0 表示素数)对 i 从 2 到 ⌊n/2⌋:如果 A[i] == 0:对 j 从 2 到 ⌊n/i⌋:A[i * j] = 1  (标记合数)返回 所有 A[i] == 0 的 i


3.3 排序问题中的模拟法

3.3.1 计数排序

题目
待排序元素均为 [0, k] 范围内的整数,通过统计方式直接放置到正确位置。

思路

  1. 统计各值出现次数;

  2. 计算累加后的位置边界;

  3. 从后向前遍历原序列,将元素按边界放入结果数组。

伪代码

函数 CountSort(A, n, k):count[0…k] = 0对 每个 x in A: count[x] += 1对 i 从 1 到 k: count[i] += count[i - 1]B[n]对 i 从 n-1 到 0:B[count[A[i]] - 1] = A[i]count[A[i]] -= 1返回 B

3.3.2 颜色排序

题目
数组元素为红(1)、绿(2)、蓝(3),按红→绿→蓝顺序重排。

思路
维护三个指针:

  • i:红色区间右边界;

  • j:当前扫描位置;

  • k:蓝色区间左边界。
    遍历时根据 A[j] 与对应区间交换位置。

伪代码

函数 ColorSort(A, n):i = 0, j = 0, k = n - 1当 j ≤ k:如果 A[j] == 1:交换 A[i] 和 A[j]; i++; j++否则 如果 A[j] == 2:j++否则:  // A[j] == 3交换 A[j] 和 A[k]; k--返回 A


3.4 拓展与演练

3.4.1 装箱问题

题目
有 6 种型号的正方体产品,边长分别为 1…6,按给定数量装入边长 6 的箱子,求最少箱数。

思路

  1. 优先装 6×6、5×5、4×4、3×3 型号;

  2. 统计剩余 2×2 和 1×1 空间,装入相应型号;

  3. 根据剩余空间与产品数量计算额外箱数。

伪代码

函数 Packing(k1…k6):n = k6 + k5 + k4 + (k3 + 3) // 4x = 5*k4 + 剩余2×2空位数(由 k3 % 4 确定)如果 k2 > x: n += ceil((k2 - x) / 9)y = 36*n - (k6*216 + k5*125 + k4*64 + k3*27 + k2*4 + k1)如果 k1 > y: n += ceil((k1 - y) / 36)返回 n

3.4.2 数字回转方阵

题目
构造 n 阶方阵,按“偶数层先列后行,奇数层先行后列”规则填入 1~n²。

思路
利用双层循环和下标交替增减,分别处理奇偶层即可。

伪代码

函数 Full(n):初始化 z[n][n]number = 1对 layer 从 0 到 ⌊(n-1)/2⌋:如果 layer % 2 == 0:  // 偶数层从 i=layer 到 n-layer-1: z[i][layer] = number; number++从 j=layer+1 到 n-layer-1: z[n-layer-1][j] = number; number++否则:  // 奇数层从 j=layer 到 n-layer-1: z[layer][j] = number; number++从 i=layer+1 到 n-layer-1: z[i][n-layer-1] = number; number++返回 z

相关文章:

  • 遥感数据处理、机器学习建模与空间预测的全流程指南——涵盖R语言(随机森林、XGBoost、SVM等)、特征提取、模型优化及生态学案例分析
  • 3、食品包装控制系统 - /自动化与控制组件/food-packaging-control
  • 162558-52-3,MCLA的化学发光是一种的超氧化物检测手段
  • Hadoop客户端环境准备
  • 【大模型面试每日一题】Day 11:参数高效微调方法(如LoRA、Adapter)的核心思想是什么?相比全参数微调有何优缺点?
  • OpenCV 中用于背景分割的一个类cv::bgsegm::BackgroundSubtractorGMG
  • FFmpeg(7.1版本)编译生成ffplay
  • Linux 系统命令使用指南1
  • 项目文档归档的最佳实践有哪些?
  • 数字电子技术基础(五十五)——D触发器
  • 微信小程序预览文件 兼容性苹果
  • 【C++】类和对象(下)
  • 桥接模式(Bridge)
  • ubuntu nobel + qt5.15.2 设置qss语法识别正确
  • 应用 | AI 自动化某讯会议转录与摘要生成系统
  • 使用英伟达 Riva 和 OpenAI 构建 AI 聊天机器人
  • 游戏引擎学习第263天:添加调试帧滑块
  • 数据报(Datagram)与虚电路(Virtual Circuit)的区别
  • 无线局域网专题 | 第十一章 | AC+AP配置
  • 【Java学习笔记】封装
  • 马上评丨全民定制公交,打开城市出行想象空间
  • 安徽亳州涡阳县司法局党组书记刘兴连落马
  • 习近平同俄罗斯总统普京会谈
  • 商务部再回应中美经贸高层会谈:美方要拿出诚意、拿出行动
  • 司法部:建立行政执法监督企业联系点,推行行政执法监督员制度
  • 解读|降准叠加政策利率、公积金贷款利率、结构性政策工具利率全线下调,影响有多大?