
简介CSP-JCCF非专业级别软件能力认证入门组初赛笔试备赛常受真题零散、答案缺失困扰这份文档正围绕这一痛点整理面向备考第一轮的中小学生与初次接触信息学奥赛的选手也可作为教练课堂练习、机构模拟自测的现成材料。包内仅含1个doc文件体积约17KB轻量易取下载后无需额外工具即可直接打开阅读和打印。目前已有797人学习。内容覆盖初赛高频考点32位int类型的存储范围、多进制混合运算、按部门分组抽人的组合计数、4位格雷码序列判别、1MB折算二进制位、C基本数据类型与循环语句辨析以及入栈出栈合法顺序判定等。每道题均给出答案并附推导过程例如组合题按“某部门抽2人”分类累加、栈题逐元素模拟进出便于对照订正错题、补齐知识盲点适合考前限时自测使用。1. 拿到这份 CSP-J 初赛 doc 先别急着对答案从 32 位 int 那道题说起大多数人打开一份 CSP-J 初赛试题 doc动作是固定的从头做到尾翻到答案页对一遍错的划个红圈然后关掉。这套流程看着闭环实际漏掉了初赛提分最值钱的一环——每道选择题背后都藏着一条可以在纸上推、可以用代码验、可以固化成模板的推理链。就拿第一题 32 位 int 的存储范围来说四个选项的区间只差一个数考的是补码表示里负数比正数多一个这个不对称性把这条吃透同类题以后再也不用背。这份 2024 年 CSP-J 组初赛的部分试题与答案解析题量不大但覆盖了数据表示、进制换算、排列组合、格雷码、存储单位、语言语法和栈的出栈序列考点密度相当高。它适合两类人刚接触入门组第一轮、想摸清题型分布的新手以及代码能写但选择题总在细节上翻车的熟手。2. 考点地图7 道选择题和 1 道栈题分别落在哪个知识域2.1 从题目反推考纲五个知识域与它们的分布第一轮笔试的题目看起来零散但它们并不是随机撒点而是按固定的几个知识域铺开的。把这份卷子里的 8 道题摊开归类会得到一张很清晰的地图计算机基础与数据表示int 存储范围、1MB 等于多少 bit、C 基本数据类型共 3 题进制与编码混合进制表达式求值、4 位格雷码序列判定共 2 题组合数学与计数10 人分 3 个部门选 4 人共 1 题程序设计语言语法C 的循环语句集合共 1 题数据结构给定入栈顺序判定出栈序列的合法性共 1 题。先做归类这件事的价值在于它把我要刷多少题换成了我要补几个域。归类之后你会发现一个关键比例这 8 道题里纯记忆性的只有 2 题基本数据类型、循环语句剩下 6 题都能在考场现场推出来。这个比例直接决定了复习策略——初赛的分数主要来自能不能在草稿纸上把过程写清楚而不是背了多少条结论。很多人复习初赛的方式是背题遇到原题会、换个数字就不会问题就出在这里。还有一层更实际的考虑。第一轮是笔试没有编译器、没有 IDE、没有报错信息所有验证都得靠手。这就要求对每个知识域的准备必须落到可手算、可自查的程度进制题要能在纸上标底数组合题要能列出分类表栈题要能画出三态变化。归类完成之后接下来每一节的解法路径都是围绕这个目标设计的。2.2 每类题的「最快解法路径」怎么定同一个知识域解法路径选错了考场上是会实打实丢时间的。下面按题型说清楚我一般怎么切。int 范围题的切法是抓不对称性。32 位有符号整数的范围是 -2^31 到 2^31-1也就是 -2147483648 到 2147483647。注意左端点的绝对值比右端点大 1因为 0 占了正数侧的一个编码位。四个选项里凡是写成两端绝对值相等的-2147483647~2147483647、-2147483648~2147483648都可以直接划掉剩下的那个就是答案。这条判据比背数字可靠得多也不怕题目改成 64 位。存储单位题的切法是记推导链而不是记结果。1KB 1024B1MB 1024KB1B 8bit所以 1MB 1024 × 1024 × 8 8388608 bit。把链条记住题目怎么改问 1GB、问多少 bit、问多少字节都能现算只记 8388608 这个数换个单位就废了。混合进制题的切法只有一条铁律先把每个数的底数标出来再统一转成十进制最后按原运算符算。绝对不要在混合进制上直接做加减乘那是最容易翻车的地方。这道题的原式是 (14₈ - 1010₂) × D₁₆ - 1101₂四个数分属三种进制任何一个底数标错结果就完全对不上选项。组合计数题的切法是分类枚举优于补集。这道题要求每个部门至少 1 人用总数 C(10,4) 减去有空部门的情况属于容斥交集部分很容易重复减或者漏减。而按哪个部门出 2 人来切分三类互斥且完备加起来就是答案不需要回加。格雷码题的切法是只用一条判据相邻两个码字异或之后二进制里只能有 1 个 1。背序列是没用的题目随便给一组看着像的序列就能骗过记忆。栈序列题同理靠感觉有没有逆序必然出错正确做法是老老实实模拟入栈出栈。2.3 一张表把题目、考点、易错点对齐把上面这些整理成一张表打印出来贴在桌前做完一遍就在高频错点那一列打勾。打勾最多的行就是你下一轮复习的重点。题号题干关键词知识域主要考点高频错点第 1 题32 位 int 存储范围数据表示补码、有符号整数边界误以为正负两端对称第 2 题混合进制表达式求值进制换算八/二/十六进制互转下标丢失导致把 14₈ 读成十进制 148第 3 题10 人选 4 人每部门至少 1 人组合计数分类枚举、组合数计算用补集算漏掉交集回加第 4 题4 位格雷码序列编码格雷码定义、相邻位差异靠背序列而非验证相邻异或第 5 题1MB 等于多少 bit存储单位KB/MB/bit 换算链漏乘 8 或把 1024 当 1000第 6 题不是 C 基本数据类型语言语法基本类型与复合类型区分把 struct 当成基本类型第 7 题不是 C 循环语句语言语法各语言控制结构差异把 repeat-until 当成 C 语法第 8 题入栈 1~6哪个出栈序列不可能数据结构栈的 LIFO 特性、模拟只用逆序对判断忽略中间态这张表还有个用法把主要考点那一列单独抄出来就成了一份八行的复习清单。如果某个考点你连名字都觉得陌生那它对应的题无论做对做错都要重新过一遍——做对可能只是蒙对。3. 手工推演进制、组合、格雷码、栈序列四类题的算穿流程3.1 混合进制表达式先把所有底数标出来再动笔原题是计算 (14₈ - 1010₂) × D₁₆ - 1101₂ 的十进制结果选项是 13、14、15、16。这道题在 doc 里显示成了 (148-10102)∗D16-11012下标全部退化成了普通字符看起来像是十进制数 148 和 10102 在做运算——这是从网页或 PDF 复制到纯文本时最常见的失真后面避坑那一章会专门讲怎么处理。正确的读法是四个数各自带底数原式中的数实际底数十进制值换算过程14八进制121×8 4 121010二进制101×8 0×4 1×2 0 10D十六进制13D 对应 131101二进制131×8 1×4 0×2 1 13代回原式(12 - 10) × 13 - 13 2 × 13 - 13 26 - 13 13对应选项 A。推演过程里有三个容易出岔子的地方。第一处是运算优先级括号先算然后乘最后减顺序错了会得到 2 × 0 0 这类离谱结果。第二处是 D₁₆ 这个写法字母 D 在十六进制里是合法的数字字符但它在纯文本里和变量名长得一样读题时要靠上下文判断——如果一个式子里同时出现 A 到 F 的字母且没有声明变量那基本就是十六进制数字。第三处是最后一个 1101₂它前面是个减号很容易被误读成乘方或者下标的一部分。我自己做这类题的习惯是读完题干先用笔在草稿纸上重写一遍每个数后面用括号标底数比如写成 (14)(8进制) 这种形式然后再开始算。多花十秒重写比算错重来省时间。这个习惯在考场上尤其值钱因为第一轮笔试没有草稿自动保存改起来很麻烦。3.2 组合计数按「哪个部门出 2 人」分类枚举原题是 10 名员工分在 3 个部门A 部门 4 人、B 部门 3 人、C 部门 3 人从中选 4 人组成工作组每个部门至少 1 人问有多少种选法。先想清楚人数分配。4 个人分到 3 个部门每部门至少 1 人那么分配方案只可能是 (2,1,1) 这一种形态——因为如果按 (3,1,0) 分就有部门没人违反条件。而 (2,1,1) 里那个2落在哪个部门正好构成三类互斥的情况这就是天然的切分点。逐类计算A 部门出 2 人B、C 各出 1 人C(4,2) × C(3,1) × C(3,1) 6 × 3 × 3 54B 部门出 2 人A、C 各出 1 人C(3,2) × C(4,1) × C(3,1) 3 × 4 × 3 36C 部门出 2 人A、B 各出 1 人C(3,2) × C(4,1) × C(3,1) 3 × 4 × 3 36。三类相加54 36 36 126对应选项 B。这里值得多说一句组合数的算法。C(n,k) 的展开是 n! / (k! × (n-k)!)但考场上没必要算阶乘用分子从 n 开始往下乘 k 项分母是 k!更快。比如 C(4,2) 4×3 / 2×1 6C(3,2) 3×2 / 2×1 3。小数字用这个算法基本不会错。再说说为什么不用补集。总选法是 C(10,4) 210。要减掉的情况是A 部门没人、B 部门没人、C 部门没人这三种但两两之间有交集比如 A、B 都没人那 4 个人全从 C 的 3 人里出根本不可能选出 4 个三三之间也有交集。容斥公式写起来是 210 - [C(6,4) C(7,4) C(7,4)] [...] - [...]每一项都要判断是否为空集稍不留神就多减或者少减。这套流程在纸面上出错概率远高于分类枚举所以我的建议是只要题目条件里出现每个 X 至少 1 个且规模不大优先分类。3.3 格雷码从定义递推到 4 位序列格雷码的定义是一组二进制编码任意两个相邻码字之间恰好只有 1 位不同。注意是恰好 1 位不是至多 1 位也不是至少 1 位。这个定义就是全部判据不需要记任何序列。题目给了四个 4 位码字序列作为选项问哪个对应数组 0 至 8 的格雷码。逐个用相邻异或验证异或结果里 1 的个数必须等于 1选项 A00000001001100100110011101011000。前七对相邻码字都只差 1 位但最后一步 0101 和 1000 异或得 1101有 3 位不同直接排除。选项 B00000001001100100110011101000101。检查 0111 和 0100 这一对异或得 0011有 2 位不同排除。选项 C00000001001100100100010101110110。检查 0010 和 0100 这一对异或得 0110有 2 位不同排除。选项 D00000001001100100110011101010100。逐对验证相邻对异或结果不同位数0000 / 0001000110001 / 0011001010011 / 0010000110010 / 0110010010110 / 0111000110111 / 0101001010101 / 010000011七对全部只差 1 位答案就是 D。这套验证流程在纸上大概需要一到两分钟但它有个巨大优势不依赖任何记忆题目怎么改都能用。而且它还能反向用来生成——如果题目问下一个码字是什么只要保证和当前码字差 1 位就行当然唯一性要靠标准生成规则第 4 章会给公式。还有个细节要注意题干写的是数组 0 至 8但四个选项都只有 8 个码字不是 9 个。这说明题干表述和选项之间存在一点不严格实际要判的是 0 到 7 这 8 个码字。遇到这类情况以选项的个数和形态为准不要因为题干写0 至 8就去找第 9 个码字那会在考场上白耗时间。3.4 出栈序列用「栈内 已出 未入」三态表判非法原题是空栈入栈元素依次为 1、2、3、4、5、61 最先入栈6 最后入栈问哪个出栈顺序不可能。选项里 D 是答案但重点是搞清楚为什么不可能。判非法最稳的办法是模拟把每一步的三态栈内内容、已出序列、尚未入栈的元素都记下来。以选项 D 的 135246 为例要第一个输出 1必须先把 1 入栈再立刻弹出此时栈空已出 [1]未入 [2,3,4,5,6]。要输出 3得把 2、3 依次压入再弹出 3此时栈内 [2]已出 [1,3]未入 [4,5,6]。要输出 5得压入 4、5弹出 5此时栈内 [2,4]已出 [1,3,5]未入 [6]。下一个要输出的是 2但栈顶是 4按 LIFO 规则必须先弹 4 才能碰到 2所以这个序列不可能实现答案是 D。用同样的方法验证选项 C 的 246531压 1、2弹 2压 3、4弹 4压 5、6弹 6弹 5、3、1。全程合法栈内状态依次是 [1] → [1,3] → [1,3] → [1,3] → [1,3,5] → [1,3] → [1] → 空。所以 C 是可能的。选项 B 的 165432 更容易看1 进 1 出然后 2 到 6 全部压入再依次弹出 6、5、4、3、2。合法。选项 A 是全部压入再全部弹出也是合法的。这里有个血泪经验很多人判这类题靠序列里有没有逆序对。比如看到 135246发现 5 在 2 前面就断定非法。这个判据是错的——选项 C 的 246531 里同样有大量大数在小数前面的情况但它是合法的。栈的合法性只跟某个元素出栈时比它后出栈的元素是否还在栈里有关跟数值大小关系没有直接联系。所以别用直觉用模拟。4. 代码验答案4 段可复现脚本把选择题变成可执行断言4.1 先把运行环境固定住Python 3.8 与 C17手工推演完之后下一步是用代码把这些推理固化成可以反复运行的断言。这么做有两个好处一是验证自己手算的结果二是把这些题改造成可以带参数的函数以后遇到同类题直接改输入。环境要求不高Python 3.8 及以上因为要用 math.comb3.8 才进标准库C17 用于验证 int 边界。不需要装任何第三方库标准库够用。建议新建一个目录四段脚本分别存成单独文件命名上带题号方便回头对照。提示这些脚本的定位是验算器不是解题器。目的是让你在怀疑自己手算结果时有个独立信源而不是替代推演过程。考场上没有 Python推演能力才是根本。4.2 进制表达式与存储单位两个函数搞定# 混合进制求值底数必须显式传入绝不靠肉眼猜 def to_dec(digits: str, base: int) - int: 把 digits 按 base 进制转成十进制digits 允许 0-9 和 A-F value 0 for ch in digits.upper(): d int(ch, 36) # 借用 36 进制解析拿到单字符数值A10 ... F15 if not 0 d base: # 越界直接报错避免把非法数字算进去 raise ValueError(f数字 {ch} 不属于 {base} 进制) value value * base d # 秦九韶算法逐位累乘 return value a to_dec(14, 8) # 14(八进制) 12 b to_dec(1010, 2) # 1010(二进制) 10 c to_dec(D, 16) # D(十六进制) 13 d to_dec(1101, 2) # 1101(二进制) 13 print(各项十进制值:, a, b, c, d) print(表达式结果:, (a - b) * c - d) # 期望 13对应选项 A # 存储单位换算链MB - KB - B - bit mb 1 print(1MB 的 bit 数:, mb * 1024 * 1024 * 8) # 期望 8388608对应选项 D逻辑上没什么花哨的核心在第 4 行那个int(ch, 36)它把单个字符当作 36 进制数解析0 到 9 得到 0 到 9A 到 Z 得到 10 到 35。这样一行就解决了十六进制字母转数值的问题不用写 if-else 分支。第 5 行的边界检查是必须的否则把8传进 8 进制时会静默算出错误结果而不是报错这属于典型的黑匣子行为。参数说明digits传字符串而不是整数是因为像 1010 这样的二进制串用整数表示会丢掉前导零而且没法区分 10 到底是二进制还是十进制。base必须显式给这是这套代码最重要的设计——强制你在调用时想清楚每个数的底数正好对应 3.1 节强调的先标底数。4.3 组合计数与栈序列把选择题变成暴力枚举from math import comb # 组合计数A 部门 4 人B 部门 3 人C 部门 3 人选 4 人每部门至少 1 人 sizes {A: 4, B: 3, C: 3} total 0 for two_in in (A, B, C): # 枚举哪个部门出 2 人 plan {A: 1, B: 1, C: 1} plan[two_in] 2 # 该部门名额改成 2 ways 1 for dept, k in plan.items(): ways * comb(sizes[dept], k) # 三个部门各自从本部选人 print(f{two_in} 出 2 人: {plan} - {ways}) total ways print(总方案数:, total) # 期望 126对应选项 B # 栈序列合法性严格按入栈出栈规则模拟 def stack_ok(seq): stack, nxt [], 1 for x in seq: while nxt x: # 把 x 及之前所有还没入栈的压进去 stack.append(nxt) nxt 1 if stack and stack[-1] x: stack.pop() # 栈顶正好是待出元素弹出 else: return False # 栈顶不是 x这个顺序拿不到 return True for seq in [(6,5,4,3,2,1), (1,6,5,4,3,2), (2,4,6,5,3,1), (1,3,5,2,4,6)]: print(seq, 合法 if stack_ok(seq) else 非法)第一段代码的关键在循环结构外层枚举哪个部门出 2 人内层遍历三个部门调comb。comb(n, k)返回 C(n,k)底层用的是高效的乘法公式不用担心阶乘溢出。这段代码的写法比手写 6×3×3 更抗改题目如果把 A 部门改成 5 人只需要改sizes字典里的一个数字其余逻辑不动。第二段代码是栈模拟的核心nxt是下一个还没入栈的元素编号这个指针stack是当前栈内容。对序列里的每个待出元素x先把 1 到 x 之间所有还没入栈的压进去然后检查栈顶是不是 x。这里有个前提假设入栈顺序是 1 到 n 的递增序列如果题目改成任意入栈序列要把nxt x改成按下标推进逻辑会复杂一些但核心判据不变。参数说明seq必须是 1 到 n 的一个排列元素不重复且都在范围内。如果传进去的序列有重复元素或者越界函数会给出错误结果而不是报错所以调用前最好加一句断言。4.4 格雷码与 int 边界一条公式 三个常量# 标准 n 位格雷码生成公式第 i 个码字 i ^ (i 1) def gray(i: int) - int: return i ^ (i 1) codes [f{gray(i):04b} for i in range(8)] print(生成序列:, codes) # 期望 [0000,0001,0011,0010,0110,0111,0101,0100]与选项 D 一致 # 相邻校验异或结果里必须恰好只有 1 个 1 def adjacent_ok(seq): for a, b in zip(seq, seq[1:]): diff int(a, 2) ^ int(b, 2) if bin(diff).count(1) ! 1: return False, (a, b) return True, None options { A: [0000,0001,0011,0010,0110,0111,0101,1000], B: [0000,0001,0011,0010,0110,0111,0100,0101], C: [0000,0001,0011,0010,0100,0101,0111,0110], D: [0000,0001,0011,0010,0110,0111,0101,0100], } for key, seq in options.items(): ok, bad adjacent_ok(seq) print(key, 合法 if ok else f在 {bad[0]}/{bad[1]} 处断开)gray(i)这一行公式来自格雷码与自然二进制的关系g n ^ (n 1)把自然数和它右移一位的结果异或就行。这个公式在纸面上也很好用——考场上如果题目问第 5 个 4 位格雷码是多少把 5 写成 0101右移一位得 0010异或得 0111一步到位不用从 0 开始一个个推。f{gray(i):04b}里的04b是格式说明符b表示二进制04表示不足 4 位时左补零。这个细节很重要如果不补零0000 这种码字会输出成 0后面int(a, 2)虽然还能解析但序列对齐会乱。选项字典那段的用法是把你怀疑的答案全塞进去让程序一次性告诉你哪些合法。这比逐个手算快也更容易发现自己漏掉的分支。C 侧验证 int 边界#include cstdio #include climits #include cmath int main() { printf(sizeof(int) %zu\n, sizeof(int)); // 常见实现是 4 printf(INT_MIN %d\n, INT_MIN); // -2147483648 printf(INT_MAX %d\n, INT_MAX); // 2147483647 printf(2^31 - 1 %.0f\n, std::pow(2, 31) - 1); // 用浮点交叉验证右端点 int a INT_MAX; printf(INT_MAX 1 %d\n, a 1); // 未定义行为不同编译器可能不同 return 0; }这段的重点不是输出结果而是最后一个 print 的注释有符号整数溢出在 C 标准里是未定义行为不是回绕成 INT_MIN。很多编译器在默认优化下确实会得到 -2147483648但这只是实现巧合不能当规范记。另外sizeof(int)也说明 int 的宽度不是标准固定的标准只保证至少 16 位今天常见的 4 字节是主流实现的约定。这两条决定了第 1 题的复习方式记 INT_MIN 和 INT_MAX 这两个常量别记溢出后的结果。5. 避坑与排查5 条从真题 doc 里踩出来的血泪经验5.1 现象按题干数字直算结果和四个选项全对不上原因doc 从网页或 PDF 复制过来时上下标全部退化成了普通字符。原题里的 14₈ 变成了 1481010₂ 变成了 10102D₁₆ 变成了 D161101₂ 变成了 11012。如果按字面当十进制算(148 - 10102) × 16 - 11012 会得到一个很大的负数跟选项完全不在一个量级。解决拿选项当校验器反推底数。原式算出来的答案必须落在 13 到 16 之间那只有把这四个数理解成小数值的进制表示才可能。具体操作是读完题干先看选项区间再看式子里的数字形态凡是出现 0 和 1 组成的长串优先猜二进制出现 8、9 以外的单个字母A 到 F优先猜十六进制。确认之后用 4.2 节的to_dec函数逐个验一遍把底数标死在草稿纸上再开始算。5.2 现象组合题算出来 119 或者 132就是得不到 126原因用补集法算的时候容斥处理错了。具体来说总选法 C(10,4) 210 是对的减掉A 部门 0 人的 C(6,4) 15 也对但接着减B 部门 0 人的 C(7,4) 35 和C 部门 0 人的 C(7,4) 35 时就出问题了——这三类之间存在交集而且B 没人且 C 没人这种情况要求 4 个人全从 A 的 4 人里选只有 1 种A 没人且 B 没人则完全不可能。少加或多加一个交集项结果就在 120 到 132 之间漂。解决换分类枚举别用补集。这道题按哪个部门出 2 人切分三类互斥完备加起来就是答案不存在容斥问题。判断标准很简单只要题目条件是每个 X 至少 1 个且 X 的个数不超过 4分类枚举的出错概率远低于补集。补集法适合至少 1 个的反面只有一种情况比如至少 1 个白球的反面是全是黑球的场景。5.3 现象格雷码题盯着选项看了五分钟每个选项的相邻对看着都差不多原因靠视觉判断二进制串像不像只差一位是不可靠的。0001 和 0011 看起来只差一位0111 和 0100 看起来也只差一位但后者实际差了两位。人眼对二进制串的位数变化不敏感尤其是位数比较多的时候。解决用异或。把相邻两个码字做按位异或结果里 1 的个数必须恰好是 1多一个少一个都不行。这一步在纸上也能做——异或的规则是同为 0、异为 1逐位扫一遍就行。4.4 节的adjacent_ok函数就是把这个过程固化下来四个选项一次性跑完哪个在哪个位置断开一目了然。从那以后我遇到格雷码题第一反应永远是写异或而不是比对序列。另一个相关的坑是题干写数组 0 至 8但选项只有 8 个码字。遇到这种表述不严格的情况以选项的形态为准不要钻牛角尖去找第 9 个。5.4 现象栈序列题把合法选项判成了非法或者反过来原因用序列里有没有逆序对当判据。这个判据的直觉来源是栈是后进先出所以大的应该先出但栈的合法性跟元素数值大小没有必然联系只跟某个元素出栈时比它后出栈的元素是否还压在栈里有关。选项 C 的 246531 里6 在 5 前面、5 在 3 前面看着全是逆序但它是完全合法的。解决老老实实模拟。具体做法是维护两个状态——下一个待入栈的编号和当前栈内容对出栈序列的每个元素执行入栈到该元素为止然后检查栈顶这两步。纸面上就用三态表栈内 / 已出 / 未入逐步记录每一步都写清楚。4.3 节的stack_ok函数是同一个逻辑的代码版本可以拿来对答案。还有一种更隐蔽的错法把入栈顺序当成可以随意调整的。题目明确说了1 最先入栈6 最后入栈入栈顺序是固定的递增序列不能为了凑出某个出栈顺序而改变入栈次序。读题时把这类约束画出来能省掉很多返工。5.5 现象把 INT_MAX 1 当作 -2147483648 记做题或写代码时踩雷原因这是从补码回绕的民间说法里来的。确实有很多编译器在默认优化下会得到 -2147483648但 C 标准里规定有符号整数溢出是未定义行为编译器可以做任何事包括直接优化掉这段代码。把它当成规范来记遇到开优化编译或者换编译器就会翻车。解决只记两个常量不记溢出结果。INT_MIN -2147483648INT_MAX 2147483647两者不对称的原因是 0 占了正数侧一个编码位。需要处理边界溢出时用long long或者显式检查别依赖回绕。另外sizeof(int)也别想当然标准只保证至少 16 位跨平台代码里该用cstdint里的int32_t就用。6. 三遍复盘法把一份 8 道题的卷子用出 3 倍效果一份只有 8 道题的初赛卷硬刷一遍大概二十分钟就没了。想让它产生持续价值得把它当成三次不同的材料来用。第一遍限时闭卷模拟真实状态。手机关掉草稿纸只给一张按第一轮笔试的节奏做遇到卡壳超过三分钟的题先标记跳过。这一遍的唯一目的是拿到一份真实的初始成绩不做任何查证。做完之后只统计两个数字完全不会的有几道蒙对的有几道。后一个数字特别关键——蒙对的题在成绩单上显示为对但在能力账本上是错混在一起就会高估自己。第二遍逐题写推导把对和会分开。这一遍不看答案对每道题包括做对的在草稿纸上完整写出推导过程然后翻到答案解析逐行比对。比对的重点不是结果对不对而是过程有没有跳步。凡是一步就写出答案、中间没有推导痕迹的题都要在题号旁标记未验证。这份卷子里的进制题和组合题最容易出现这种情况——看着眼熟答案脱口而出但真让你重算一遍就卡住了。第三遍隔期重做只看题干。做完第二遍之后隔三天做一次错题隔七天再做一次。这一次把答案页遮住也不允许看自己之前的推导完全裸做。两次都做对的题可以划掉任何一次出错的题回到第二遍重新走流程。这个循环会筛出真正的薄弱点通常不超过三道。配合这个流程我做了一张错因归因表做完第二遍之后按类别填错因类型典型表现这份卷子里的对应题补救动作概念模糊知道考什么但说不清定义第 1 题 int 边界、第 4 题格雷码回到定义原文用自己的话复述一遍判据错误用感觉代替规则第 4 题背序列、第 8 题看逆序对换成可执行的判据异或、模拟计算失误思路对但算出别的数第 2 题进制、第 3 题组合手算过程分步写不跳步读题失真把 14₈ 读成 148第 2 题混合进制先按选项区间反推底数再动笔记忆混淆记成回绕而非未定义第 5 题存储单位、int 溢出只记常量和公式不记结论性规律表里判据错误这一行是我自己踩得最狠的。早些年做栈序列题我全靠扫一眼序列里有没有降序段正确率大概六成还以为是题出得怪。后来强迫自己每次都在纸上画三态表正确率立刻上去了代价是每道题多花一分半钟。这笔账算下来是划算的一分半换一道题的分比做错重来便宜太多。还有个小技巧适合把这份 doc 用得更透把选择题的选项删掉改造成填空题。原题问32 位 int 的范围是就把选项全删只看题干逼自己从零写出答案。这一步比做完再对答案狠得多因为它切断了排除法这条捷径。doc 格式的好处就在这里——你可以直接编辑另存成一份无选项版本隔一段时间做一次。同一份题改造前是 8 道选择题改造后是 8 道填空等于凭空多出一套卷子。最后说个我自己的习惯。每次复盘结束我会在卷子首页写一句下次遇到这类题第一件事做什么比如进制题先标底数、栈题画三态表、格雷码写异或。这句短句比任何笔记都管用因为它在考场上能被瞬间回忆起来而长篇笔记不能。希望帮到你。本文还有配套的精品资源点击获取