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

第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
http://www.xdnf.cn/news/4549.html

相关文章:

  • SDC命令详解:使用get_ports命令进行查询
  • 浅谈广告投放从业者底层思维逻辑
  • C语言 指针(8)
  • 第七章 模板制作工具
  • ubuntu 挂载硬盘
  • 当“信任”遇上“安全”:如何用Curtain Logtrace记录文件操作活动 守护团队与数据的双重底线?
  • 2398.预算内的最多机器人数目 滑动窗口+单调队列
  • springboot集成langchain4j记忆对话
  • 通道注意力-senet
  • HDMI布局布线
  • Loly: 1靶场渗透
  • 大模型 Function Calling 学习路线图
  • Solana批量转账教程:提高代币持有地址和生态用户空投代币
  • 缓存菜品-04.功能测试
  • C++ 静态成员
  • 大模型系列(四)--- GPT2: Language Models are Unsupervised Multitask Learners​
  • Java 多线程编程:从基础到实战!
  • Ceph集群OSD运维手册:基础操作与节点扩缩容实战
  • MSTP 实验拓扑配置(ENSP)
  • 自动化创业机器人:现状、挑战与Y Combinator的启示
  • hadoop中的序列化和反序列化(3)
  • React学习路线-Deepseek版
  • 搭建spark伪分布集群
  • windows10 环境下通过huggingface_hub下载huggingface社区模型
  • 子集树算法文档
  • 驱动开发硬核特训 · 专题篇:Vivante GPU 与 DRM 图形显示体系全解析(i.MX8MP 平台实战)
  • 机器学习在信用卡欺诈检测中的应用思考
  • 4.9/Q1,GBD数据库最新文章解读
  • Admyral - 可扩展的GRC工程自动化平台
  • 【MCP】function call与mcp若干问题整理