说实话第38次CSP我是裸考去的。不是报名前不重视而是那段时间确实被各种事挤占连续三个月没碰过OJ。键盘一上手最明显的感受不是“算法不会”而是连最基本的边界判断都开始犹豫。第一题磕磕绊绊写完心里已经有点虚翻到第二题题面是一大段关于机器人执行指令的故事看着像扫雷机器人又像仓库搬运车当时我第一反应是——完了这是不是又得建图跑搜索。但等我冷静下来把题面读完才发现这题本质上就是一道典型的“指令模拟”一个机器人在网格上动每走一步、每做一件事都对应一个确定的状态变化只要把状态维护好代码写对分就到手了。那场考试我的第二题做得不算快但好在没出大错。考完回来自查我花了整整一周把近几届CSP第二题的套路重新梳理了一遍这篇“机器人复健指南”就是从那轮总结里沉淀出来的。这篇东西适合三类人马上要考CSP但最近刷题量明显下降的刷题不少但第二题总是“会做但AC不了”的以及看到机器人、网格、指令这类题面就下意识发怵的。我会从题目拆解、代码骨架、踩坑实录和复健计划四个层面展开保证你读完能直接拿去复现。1. 从“手生”说起第38次CSP第二题的定位与出题惯性CSP的五道题难度是阶梯式的。第一题基本是送分考最基本的输入输出和循环第二题就开始动真格了它通常不会考多么复杂的算法但一定会考“你能否把题面描述的规则一丝不苟地翻译成代码”。第三题开始才涉及更复杂的结构、搜索或动态规划。所以第二题在整张卷子里的角色非常微妙——它是你进入中间难度之前的“稳定性测试”。我翻过近十次CSP的真题发现第二题有一个非常稳定的出题惯性模拟题年年不缺席。只不过每年换一层包装——有时是停车场计费有时是电梯调度有时是流水线任务第38次轮到了机器人。你仔细看题面就会发现这类题的内核高度一致给定一个有限的环境一个实体在里面按照一系列规则动作过程中你需要维护若干个状态量最后输出某个累计结果。为什么出题人偏爱机器人因为机器人这个载体天然自带三要素位置、朝向、动作。位置可以用二维坐标表示朝向可以用一个方向值表示动作则是题面规定好的指令集。这三样东西凑齐了一道合格的模拟题就诞生了。而且机器人题材还有一个好处——题面可以写得很“智能”让一部分考生误以为要上搜索、要上路径规划实际上只要老老实实模拟就行。这种“先用背景吓唬人、再考察基本功”的套路就是第二题最常见的心理战。从实际分数分布来看第二题AC与否往往直接影响全国排名百分比。第一题大家基本都会第三题很多人做不出来第二题就成了分水岭。我身边有不少朋友第一题和第三题都拿了分唯独第二题因为细节写崩了最终排名比预期低了一大截。原因很简单第三题没写出来不丢人第二题没AC才是真可惜。所以复健的第一步就是先认清第二题在整场考试里的定位它不是用来考智商的它是用来考你的细心和手感稳定性。接下来我们就把这种“披着机器人外壳的模拟题”拆开看看看它到底在考察哪些不变的东西。2. 题面拆解三步法机器人模拟题的底层模型不管题面把机器人包装成扫地机、搬运车还是巡检无人机只要你按下面三步走基本都能在五分钟内把题面抽成一段清晰的逻辑。2.1 第一步找出“实体状态”先问自己一个问题这个机器人在题面描述的世界里有哪些东西是“会变的”绝大多数情况下答案逃不出这几样当前位置坐标通常记作 (x, y)当前朝向我习惯用整数 0、1、2、3 表示东、南、西、北题目要求累计的结果比如清扫得分、行驶距离、搬运数量如果涉及“重复访问”的概念还需要一个集合或标记数组记录哪些格子已经被处理过。务必在动笔写代码之前先把这些状态量写在草稿纸上。哪怕只是几个变量名也能避免你写到一半才发现遗漏。我在第38次考试里最大的收获就是这个习惯拿到题先列状态而不是直接开写。2.2 第二步找出“指令动作”第二步就是把题面中所有可能的指令全部枚举出来并且逐个说清楚“它对状态做了什么”。以我当时遇到的第38次第二题的通用形态为例题面大致是这样一个模型机器人处在一个 n×n 的网格里每个格子上有一个分值机器人会顺序执行 m 条指令指令只有几种F 前进一格、L 左转、R 右转、C 清扫当前格清扫一个格子时如果这个格子是第一次被清扫就累加该格子的分值重复清扫不得分执行完所有指令后输出总分。这就是一个非常典型的题面。你可能会说“等等原题不一定长这样吧”没错原题的细节我记不得那么精确了网上也能搜到各种版本的复盘但核心模型可以说完全一致——一个实体、一组指令、一个计分条件。这就是为什么我说“模型比题面重要”。2.3 第三步找出“计分与边界条件”第三步最关键也是最容易出错的地方搞清楚“什么情况下算有效动作”和“什么情况下算边界”。对于上述模型至少要想清楚这几个问题指令让机器人前进一格但前方已经是网格边界甚至会越界这步算数吗有的题面规定越界指令直接忽略有的规定机器人原地不动甚至有规定“撞墙本轮结束”的。清扫计分时“第一次清扫”如何判定如果机器人反复在一个格子上执行C指令第二次开始还有没有分得分累加会不会超过 int如果 m 很大、分值很大得分变量就必须开 long long。这些细节看起来琐碎但每一个都对应一个真实的扣分点。我自己在复健刷题时吃过最大的亏就是在边界条件上“想当然”——题面没说越界怎么办我就默认忽略结果对拍时发现标准答案把越界当成了“原地踏步”。从那以后我拿到题第一件事就是把“边界”两个字画个圈确认题面有没有交代。没有交代的按照最宽松的理解写然后在小样本上验证。3. 考场代码骨架这份模板帮我稳住了第二题拆完模型之后代码实现其实就那么几块输入、状态初始化、指令循环、计分更新。我直接给出一份我目前最常用的机器人模拟题代码骨架它的结构足够通用遇到同类题改改指令集和计分规则就能用。#include bits/stdc.h using namespace std; int main() { int n, m; cin n m; vectorvectorint score(n, vectorint(n, 0)); for (int i 0; i n; i) { for (int j 0; j n; j) { cin score[i][j]; } } // 方向编码0东、1南、2西、3北 // 注意dx、dy与方向编号一一对应 int dx[4] {0, 1, 0, -1}; int dy[4] {1, 0, -1, 0}; int x 0, y 0, dir 0; long long total score[0][0]; vectorvectorbool visited(n, vectorbool(n, false)); visited[0][0] true; for (int i 0; i m; i) { char op; cin op; if (op L) { dir (dir 3) % 4; // 左转顺时针编号下等价于-1 } else if (op R) { dir (dir 1) % 4; // 右转1 } else if (op F) { int nx x dx[dir]; int ny y dy[dir]; // 越界处理按“忽略该条指令”实现 if (nx 0 || nx n || ny 0 || ny n) { continue; } x nx; y ny; } else if (op C) { if (!visited[x][y]) { visited[x][y] true; total score[x][y]; } } } cout total endl; return 0; }这份代码的核心逻辑非常直白但里面有三个设计细节我觉得比代码本身更值得说。3.1 方向编码与dx/dy为什么必须分开写很多初学者喜欢把方向写成一个二维数组的“朝向向量对”比如每次转向时直接改x和y的增量或者用字符串存方向。我的建议是永远使用dir这个整数 dx[4]、dy[4]两个数组的组合。原因很简单转向本质上是对方向编号做取模运算而前进本质上是用方向编号去查表。把这两个动作分开你就不用在转向逻辑里去处理坐标差出错概率会大幅下降。3.2 visited用二维布尔数组还是set在网格范围固定且不大时我优先用vectorvectorbool。它有两个好处一是查询和修改都是 O(1)二是坐标直接就是下标不需要额外计算哈希值。只有当网格很大而且坐标比较稀疏时才考虑unordered_setlong long用x * n y或(x 32) ^ y做坐标编码避免把两个整数拼字符串开销真的不值。3.3 long long到底该不该开很多题目看着分值和步数都不大但偏偏就有人因为不开 long long 在最后几个测试点爆掉。我的原则是只要题目没明确说“结果不超过32位”一律开 long long。反正多写几个字节不要钱但一个溢出直接送掉20分就太冤了。4. 踩坑实录五个最容易丢分的细节代码写出来是一回事能不能AC是另一回事。第二题最大的特点就是题面看着简单坑全藏在细节里。下面这五个坑是我自己踩过、也在别人代码里见过的全部列出来你一条一条对照着检查。4.1 坐标系的“东南西北”和“行x列y”混淆这是新手最容易踩的坑。我们习惯的数学坐标系 x 轴向右、y 轴向上但编程里的二维数组是 x 向下、y 向右。也就是说如果你把朝南定义为 x 增大把朝东定义为 y 增大那么“东、南、西、北”对应的增量就是朝向方向编号dxdy东001南110西20-1北3-10我在复健时发现很多人会把“朝北”的 dy 写成 -1 或者把“朝东”的 dx 写成 1就是因为没厘清矩阵坐标的特性。这个表你每次写题前都过一遍能省下大量查错时间。4.2 转向的取模方向搞反左转是(dir 3) % 4还是(dir 1) % 4这个问题取决于你的方向编号是“顺时针”还是“逆时针”排列。在我给的表里方向编号是顺时针排列的东→南→西→北所以右转是 1左转是 3。如果你的方向数组是逆时针排列东→北→西→南那右转就变成 3左转变成 1。这个最容易错的地方在于代码编译不会报错小样例也可能刚好碰上能过但一旦步数变多就会乱。解决方法是写完后立刻用一个“先左转再前进”的简单样例在草稿纸上手动模拟一遍看看机器人实际去的位置对不对。4.3 visited判定与计分逻辑的绑定位置我看到过很多人把计分写在前进的代码块里写成“每前进到一个新格子就加一次分”。这在某些题目里是对的但在“机器人必须执行清扫指令才得分”的模型里就是错的。这种题目中机器人可能连续三次前进经过某个高分格子但始终没执行C指令那就不该加分。所以计分逻辑一定要跟触发它的指令绑定而不是跟位置变化绑定。我自己的习惯是在代码里把“位置更新”和“计分判定”两块严格分开。前进指令负责改位置清扫指令负责改visited和total谁也不要越权。4.4 数组基址“从1开始”还是“从0开始”很多题面为了方便描述会说机器人从 (1, 1) 出发网格下标也是 1 到 n。如果你直接把全部存储开成 n1 大小并且把 (1,1) 作为起点那代码读起来确实直观但要注意所有数组访问都要保持一致。最怕的是你存储用 n1循环读取却从 0 开始或者反过来那样就会出现“莫名其妙的错位”。我的建议是不管题面怎么写统一改成 0-based 处理起点就是 (0, 0)最后输出时如果需要再换算。这样向量数组和边界判断都会自然很多不容易漏。4.5 无操作指令的漏判与误判机器人模拟题里经常混入一些“什么都不做”的指令比如暂停、充电、等待、空转。这种指令的存在不是为了让题面更复杂而是专门坑那些用if - else if链写到一半就默认所有指令都有动作的人。如果你用了else而不是else if那么一个未识别指令就可能被当成默认情况执行错动作。我在第38次那场就差点在这个上面栽跟头。当时我看到指令集里有一个 S 开头的东西下意识以为它代表“前进”后来细读题面才发现是“原地停留”。所以每看到一个不认识的指令先定位它是“有动作”还是“无动作”不要想当然。5. 21天复健计划把“会做”变成“一次做对”CSP第二题光靠考前看这篇指南是不够的你得把状态找回来。这里的“复健”不是重新学算法而是把“把题面翻译成代码、并且一次写对”的手感练回来。下面这个21天计划是我根据自己从“手生”到“稳定AC”的过程总结出来的亲测有效。5.1 阶段一3天基础恢复重写经典模拟题复健头三天不要追求新题去把CSP官网的历年真题第一题和第二题翻出来重写。第一题帮你找回基本的输入输出、循环、数组操作的手感第二题则帮你重新适应“读题面、找状态、写循环”的节奏。每天2到3道就够了重点不是数量而是每道题都保证能自己独立写完并一次通过样例。这个阶段最容易出现的问题是“看得懂题但一写就卡”。不要慌卡住了就回头翻我之前给的代码骨架对着骨架改。手感的恢复没有捷径就是重复。5.2 阶段二7天专项训练专攻“包装型模拟题”第二阶段要找各种不同包装的模拟题来练昨天的机器人扫雷今天的电梯调度明天的停车场计费。训练目标只有一个——快速剥掉题面的外壳找到“实体状态、指令动作、计分条件”这三件套。具体操作是拿到题先不看样例解释直接在白纸上写“状态有哪些、指令有哪几种、计分条件是什么”写完再对比题面确认。这个阶段我推荐直接在CSP题库里按年份从新往旧刷或者去OJ平台上搜“模拟”标签的题目。每天2道左右坚持7天你对模拟题的感觉会完全不一样。5.3 阶段三7天限时模拟强制40分钟以内第三阶段开始就要进入“考试模式”了。CSP第二题的合理用时是30到40分钟超过这个时间就会挤压后面题目的时间。所以每次训练必须计时从读题到提交全程不超过40分钟。如果超时了不管AC没AC先停下来复盘是题面读慢了还是边想边写浪费了时间亦或是纠结某个细节太久。我当时复健时给自己定的硬指标是整套模拟卷前两题合计40分钟收工。一开始很难经常第二题写到45分钟但练了5次之后基本能稳定在35分钟左右。这个阶段你还会发现一个规律——大多数超时都发生在“边界条件没想清楚就开写”的情况下这正好验证了前面说的边界要提前确认不能写一半再回来猜。5.4 阶段四4天错题复盘建立个人checklist最后4天不要狂刷题了重点放在复盘上。把前面刷过的所有WA过的题重新看一遍每一道都问自己三个问题我是哪一步开始错的是题意理解错了还是代码实现笔误这个错误属于哪一类坐标、边界、取模、读入、类型溢出还是指令漏判下一次我怎么才能避免同类错误然后把答案浓缩成一份属于你自己的checklist。我的checklist大概长这样方向数组先对表转向前看方向编号是顺时针还是逆时针越界指令按题面规定处理计分只看触发它的指令所有累计和默认long long所有数组下标统一0-based没有默认动作的 else。这份清单考前过一遍比临时抱佛脚刷十道题都管用。说回我自己。第38次CSP那场我因为复健不充分第二题做得并不算行云流水但好在提前养成了列状态、对方向表、开long long这些肌肉记忆最终没丢不该丢的分。那次之后我最大的体会是CSP第二题根本不考天赋它考的是你有没有一套固定的、稳定的做题流程。只要把这套流程练成习惯哪怕中间停刷几个月重新捡起来也只需要两个星期。希望你下次走上考场的时候看到机器人三个字心里想的不是“完了又要写搜索”而是“来了又是老朋友”。