大模拟

没有高深算法,考的是把复杂规则"翻译"成正确代码的工程能力

一、什么是大模拟

大模拟题的特点是:规则繁琐、边界密集、没有算法捷径,按题意一步步实现即可,但代码长、细节多、极易写挂。历年 CSP-S 的 T1/T3 常客:2020 儒略日(日期换算)、2023 结构体(类型系统)、2019 格雷码等。

生活类比:大模拟就像照着一份 20 页的宜家说明书组装家具。不需要你懂力学原理,但漏装一个垫片、装反一块板,最后柜子就是歪的。得分高低取决于流程和细心,不取决于聪明。
考场定位:大模拟题往往是"区分度守门员"——大家都会做,但满分率低。策略是预留充足时间 + 结构化写法 + 小样例逐行走查,而不是拼手速。

二、标准解题流程

  1. 读题列要素:把规则拆成一张清单:有哪些对象、对象有哪些属性、每条规则触发什么变化。写在草稿纸上,不漏一条。
  2. 设计数据结构:每个对象一个 struct,属性与清单一一对应;能用数组就不用 map。
  3. 拆函数:每条独立规则一个函数(如 move()、leapYear()),主流程只负责按顺序调用。函数越短,错得越少。
  4. 小样例手算:写完先用题目的样例在纸上走一遍代码,再跑程序对照。大模拟的调试成本远高于预防成本。
  5. 造边界数据:n=1、最大 n、全相同、环形跨边界、闰年 2 月……逐个验证。

三、高频技巧:环形结构用同余

环形排列(围成一圈的玩具、循环队列、星期推算)中,位置变化统一写成:

新位置 = (pos + step % n + n) % n

+ n 是为了吃掉负数(逆时针走时 step 为负),保证结果落在 [0, n)。一切"转圈"问题都不要写 if 判断越界,用同余一行解决。

0 1 2 3 +1:编号增大方向 −1:编号减小方向 n = 4 的环 (0 − 1 + 4) % 4 = 3,自动"绕回"
环形移动:同余公式自动处理"绕回",无需特判

实例:P1563 玩具谜题的方向规律

玩具有朝向 face(0 朝内 / 1 朝外),指令有方向 dir(0 左 / 1 右)。把四种组合画在圆圈上验证,可得唯一需要记的规律:

face == dir → 沿编号减小方向走;face ≠ dir → 沿编号增大方向走
朝向 face指令 dirface 与 dir 关系下标变化
0(朝内)0(左数)相同减 s
0(朝内)1(右数)不同加 s
1(朝外)0(左数)不同加 s
1(朝外)1(右数)相同减 s

为什么朝内朝外会相反?想象你站在圆圈上:面朝圆心时,你的左手边是逆时针(编号减小方向);转过身面朝圈外,左手边就变成了顺时针(编号增大方向)。自己比划一次就再也不会记错。

这题的唯一难点就是方向。务必自己画一个 4 个位置的圆圈,把 (face, dir) = (0,0)、(0,1)、(1,0)、(1,1) 四种情况各走一格验证——考场上靠背诵不如靠画图。

四、实例:日期类大模拟(2020 儒略日 P7075)要点

五、易错点清单

六、练习

配套小测(5 题,即时判分)