CSP-J初赛选择题高频考点与答题动作拆解
简介面向准备CSP-J初赛的信息学初学者与在校学生这份文档整理了2024年CSP-J组初赛部分试题及参考答案适合用于考前自测、题型熟悉和概念查漏补缺。压缩包内共1个doc文档大小约17KB排版便于电脑阅读、打印批注或按题块拆分练习。题目覆盖32位int取值范围、进制转换与运算、部门抽选组合计数、格雷码序列、存储单位换算、C基本数据类型与循环语句、栈的出入栈顺序判断等初赛常见考点并在每题后附答案与简要解析文档以单项选择题为主并含栈操作类编程题示例答案解析强调进制换算、组合分类和栈状态推演等基础方法便于对照复盘解题思路。已有797人学习适合希望用较短时间把握初赛选择题风格、检验基础知识掌握程度的考生参考。1. 先看清 CSP-J 组初赛的选择题盘面基础题才是拉分点CSP-J 组初赛的选择题并不玄学真正拉开差距的往往不是偏题而是计算机基础、进制换算、组合计数和栈模拟这些固定盘面。从教育考试的角度看初赛像一张结构化试卷前几题考边界记忆中间题考分类计数和编码规则后段用栈和语法判断筛掉只背结论的人。拿分的关键不是把每道题都当新题而是把题型归到“边界、换算、分类、模拟”四类里按固定动作走。适合已经学过基础语法、但做题速度不稳的考生也适合二战时想把选择题错误率压下去的备考者。后面按题号拆开讲每题都给可复用的答题动作。2. 计算机基础高频考点int 范围、进制混合运算与存储单位换算计算机基础题在初赛选择题里属于“会就是会、不会就只能猜”的部分但它并不要求你背一大堆冷门参数而是反复考几个边界有符号整数的范围、进制混合运算的拆解顺序、字节与二进制位的换算链。这三类题一旦用错动作错误会非常稳定int 范围总是差一进制题总是看丢下标存储单位总是算到字节就停。下面用三道真题把动作拆开每道题都给出“先写什么、再算什么、最后查什么”的顺序。2.1 32 位 int 的边界怎么记题目32 位 int 类型的存储范围是。选项 A 为 -2147483647~2147483647B 为 -2147483647~2147483648C 为 -2147483648~2147483647D 为 -2147483648~2147483648。答案选 C。这道题的考点不是“记住一串数字”而是知道 n 位有符号整数的通式范围是 -2^(n-1) 到 2^(n-1)-1。32 位代入后左端是 -2^31右端是 2^31-12^31 等于 2147483648所以左端是 -2147483648右端是 2147483647。很多考生把右端写成 2147483648是把“2 的 31 次方”直接当成了最大值忽略了有符号整数还要给符号位留位置最大值要比 2^31 少 1。答题时我一般先在草稿上写“n 位有符号-2^(n-1) ~ 2^(n-1)-1”再代入 n32最后检查左端绝对值是否比右端大 1。这个检查动作能挡住大多数边界题如果左端是 -2147483647右端是 2147483647左右绝对值相等说明最小负数少算了一个如果右端出现 2147483648说明最大值多算了一个。选项 D 就是两边都多算看起来“对称”反而最容易骗人。提示int 范围题不要靠手算 2 的幂硬背先把通式写出来再代入位数。考场上一行通式比背十个数字稳。2.2 进制混合运算的拆解顺序题目计算 (14₈ - 1010₂) × D₁₆ - 1101₂ 的结果并选择答案的十进制值。选项 A 为 13B 为 14C 为 15D 为 16。答案选 A。这道题在原始题面里下标容易被压平看起来像“148-10102”和“D16-11012”于是有人把 14₈ 读成一百四十八把 1010₂ 读成一万零一百零二把 D₁₆ 读成 D 乘 16。正确的读法是14₈ 是八进制数1010₂ 是二进制数D₁₆ 是十六进制数1101₂ 是二进制数。先逐项转十进制14₈ 1×84 121010₂ 82 10D₁₆ 中 D 表示 131101₂ 841 13。原式变成 (12-10)×13-13 2×13-13 13。答题动作分三步第一步补下标把每个数的进制写在右下角第二步逐项转十进制不要跳步第三步按原式的括号和运算符顺序计算。最容易翻车的地方是“转完十进制后把运算符看错”比如把乘号看成加号或者把最后的减 13 漏掉。还有一点十六进制里的 A 到 F 是数字不是字母变量D₁₆ 就是十进制的 13不是 D 乘 16。如果题面排版把下标吃掉了不要急着按表面数字算先看选项和数字特征出现 14₈、1010₂、D₁₆、1101₂ 这种组合基本可以判断是不同进制的混合运算。把下标补回去题目立刻变成小学算术。这个习惯在初赛里很值钱因为一道题丢分往往不是不会转进制而是读题时把进制信息读丢了。2.3 1MB 到 bit 的换算链题目记 1KB 为 1024 字节byte1MB 为 1024KB那么 1MB 是多少二进制位bit选项 A 为 1000000B 为 1048576C 为 8000000D 为 8388608。答案选 D。换算链要一级一级走1MB 1024KB1KB 1024B所以 1MB 1024×1024B 1048576B1B 8bit所以总位数是 1048576×8 8388608bit。选项 B 是只算到字节就停了选项 A 是把 1MB 当成 1000000 的近似值选项 C 是把 1000000 字节直接乘 8。三个干扰项都对应一种常见的半截计算。这类题我建议在草稿上画一条链MB → KB → B → bit每走一步写一次乘数。先统一到字节再乘 8不要一边换单位一边乘 8否则很容易漏乘或多乘。最后检查数量级1MB 大约是一百万字节乘 8 后应该是八百多万 bit选项 D 的 8388608 正好在这个量级如果算出来只有一百多万说明只算到了字节。2.4 三题共用的检查动作这三道题表面上看是三个知识点实际共用一套动作公式先行、下标补齐、单位链写全。int 范围题先写通式进制题先补下标存储单位题先画换算链。它们都不是“背答案”能稳定解决的题因为选项会故意把边界、下标和单位藏起来。考场上做完这三类题不要立刻跳走用十秒钟回看左端和右端是否差一每个数的进制是否标了最后一位是否乘了 8。这个回看动作比多做一道新题更划算。3. 语言语法判断题C 基本类型与循环语句的排除法语言语法判断题在初赛里通常被当成“送分题”但送分题也有固定的坑题目问“不是”的时候考生容易选成“是”选项里混入其他语言的关键字时考生容易按“眼熟”来选。这一类题不考复杂语法考的是边界感和排除法。下面两道真题分别对应“基本数据类型”和“循环语句”答题动作都是先定性、再排除、最后回看题干里的“不是”。3.1 基本数据类型与 struct 的边界题目以下哪个不是 C 中的基本数据类型选项 A 为 IntB 为 floatC 为 structD 为 char。答案选 C。C 的基本数据类型主要包括整型、浮点型、字符型、布尔型和空类型等struct 是用户自定义的复合类型用来把多个成员组织在一起不属于基本数据类型。选项 A 的 Int 首字母大写严格说 C 关键字是 int 小写但这类题通常考“类型分类”不会在大小写上设卡float 和 char 都是基本类型struct 明显是自定义类型。答题时先问自己“这个选项是不是语言自带的算术类型”如果不是再确认它是不是用户定义类型。这道题最容易错的不是不知道 struct而是看到 Int 首字母大写就犹豫最后把 A 选成“不是基本类型”。我的处理方式是先按概念分类把 struct 划到“自定义/复合类型”把 Int、float、char 划到“基本类型候选”题干问“不是”直接选 struct。大小写问题如果题目没有明确考关键字拼写就不要自己加戏。初赛选择题的题干通常有一个最明显的分类错误抓住它比抠细节更快。3.2 循环语句的识别题目以下哪个不是 C 中的循环语句选项 A 为 forB 为 whileC 为 do-whileD 为 repeat-until。答案选 D。C 的循环语句是 for、while、do-while 这三种repeat-until 是别的语言里的直到循环C 不支持。这道题不需要分析循环语义只需要认语言归属。答题动作是先圈出题干里的“不是”再逐个看选项是不是 C 关键字。for、while、do-while 都是常见循环结构repeat-until 带连字符看起来就不像 C 的写法直接排除。这类题的干扰项往往来自其他编程语言考生如果学过多种语言反而容易“眼熟选错”。我的习惯是先在草稿上写“C 循环三件套for、while、do-while”然后拿选项去对。对不上的就是答案。题干里的“不是”要圈出来因为这类题有时会把“以下哪个是循环语句”和“以下哪个不是循环语句”混着出读题时少看一个“不”字后面全白算。3.3 这类题的排除法模板语法判断题的通用模板可以压成三步第一步定性判断题目问的是“基本类型”“循环语句”还是“关键字”第二步排除把明显属于该类别的选项划掉第三步回看题干确认问的是“是”还是“不是”。题 6 中struct 是复合类型排除掉基本类型候选题 7 中repeat-until 不是 C 循环直接锁定。两步都不需要复杂推理关键是不要被选项的熟悉感带跑。题号题干关键问法第一动作答案锁定6哪个不是基本数据类型区分基本类型与自定义类型struct7哪个不是 C 循环语句列出 C 循环三件套repeat-until这张表不是让你背题而是提醒自己语法判断题先找“类别边界”再找“语言归属”。做完后回看题干里的“不是”能挡住一大半粗心失分。4. 组合计数、编码与栈三类固定模型的答题路径组合计数、格雷码和栈序列题看起来跨度很大实际都是“模型题”题目给一个规则考生要按规则一步步推不能凭感觉选。组合计数考分类不重不漏格雷码考相邻码的差异位数栈题考入栈和出栈的先后约束。这三类题在初赛里出现频率高而且答案往往可以通过固定动作推出来。下面按题号拆开最后给一个栈模拟的代码模板方便手算后复核。4.1 每个部门至少一人先定“2 人部门”题目某公司有 10 名员工分为 3 个部门A 部门有 4 名员工B 部门有 3 名员工C 部门有 3 名员工。现需要从这 10 名员工中选出 4 名组成一个工作组且每个部门至少要有 1 人。问有多少种选择方式选项 A 为 120B 为 126C 为 132D 为 238。答案选 B。这道题的分类入口是“4 人分到 3 个部门每个部门至少 1 人”。人数分配只有一种型2、1、1。也就是说一定有一个部门出 2 人另外两个部门各出 1 人。接下来按“哪个部门出 2 人”分类A 出 2 人时B、C 各出 1 人方案数是 C(4,2)×C(3,1)×C(3,1)6×3×354B 出 2 人时A、C 各出 1 人方案数是 C(3,2)×C(4,1)×C(3,1)3×4×336C 出 2 人时A、B 各出 1 人方案数是 C(3,2)×C(4,1)×C(3,1)3×4×336。三类相加543636126。答题动作是先写“人数分配型”再按“2 人部门”分类最后用乘法原理算每一类、用加法原理合并。最容易错的地方是只算 A 出 2 人的情况得到 54 就选 A或者把“至少一人”理解成“指定部门至少一人”漏掉另外两个部门也可能出 2 人。检查时看总数126 比 54 大说明分类合并后确实覆盖了更多情况如果算出来比单一分类还小基本可以判定漏类。出 2 人的部门算式结果AC(4,2)×C(3,1)×C(3,1)54BC(3,2)×C(4,1)×C(3,1)36CC(3,2)×C(4,1)×C(3,1)36合计5436361264.2 格雷码相邻只差一位题目以下哪个序列对应数组 0 至 8 的 4 位二进制格雷码选项 A 为 00000001001100100110011101011000B 为 00000001001100100110011101000101C 为 00000001001100100100010101110110D 为 00000001001100100110011101010100。答案选 D。格雷码的判定规则很直接相邻两个码只有一位二进制不同。答题时不要只看开头几个数“像不像”要把每一对相邻码拿出来做异或数一数结果里有几个 1。D 序列的相邻对是 0000-0001、0001-0011、0011-0010、0010-0110、0110-0111、0111-0101、0101-0100每一对异或后都只有一位是 1。A 序列最后 0101-1000 异或得到 1101有三位不同B 序列 0111-0100 异或得到 0011有两位不同C 序列 0010-0100 异或得到 0110有两位不同。所以只能选 D。这类题的手算动作是“逐对异或数 1 的个数”。不要只检查前三四对因为干扰项往往在前面做得像最后两对才露馅。格雷码还有一个辅助判断相邻码变化的那一位有规律地轮换但初赛选择题不需要推到生成规则逐对检查已经够快。做完后回看最后一对确认没有漏查这一对经常是答案的分水岭。4.3 栈题合法出栈序列的模拟原则题目给定一个空栈支持入栈和出栈操作。若入栈操作的元素依次是 123456其中 1 最先入栈6 最后入栈下面哪种出栈顺序是不可能的选项 A 为 654321B 为 165432C 为 246531D 为 135246。答案选 D。栈题的核心约束是“后进先出”一个元素要出栈要么它已经在栈顶要么它还没入栈、需要继续压栈。判断一个出栈序列是否合法最稳的方法是模拟按 1 到 6 的顺序入栈每压入一个元素就看栈顶是不是当前目标出栈元素如果是连续弹出如果不是继续压下一个如果所有元素都压完了栈顶还不是目标元素就说明这个序列不可能。A 序列可以这样走1 到 6 依次入栈6 出5 出4 出3 出2 出1 出。B 序列1 入栈后立刻出栈然后 2 到 6 依次入栈6 出5 出4 出3 出2 出。C 序列1 入2 入2 出3 入4 入4 出5 入6 入6 出5 出3 出1 出。D 序列要求先出 1、3、5再出 2、4、6当 3 出栈时1、2 的先后关系已经被栈固定后面不可能再按 2、4、6 的顺序顺利弹出。手算容易乱可以用下面的代码复核。def can_pop_sequence(pushed, popped): stack [] j 0 # 待验证出栈序列的指针 for x in pushed: stack.append(x) # 按入栈顺序压栈 # 栈顶等于当前目标时连续弹出 while stack and j len(popped) and stack[-1] popped[j]: stack.pop() j 1 return j len(popped) cases { A: [6, 5, 4, 3, 2, 1], B: [1, 6, 5, 4, 3, 2], C: [2, 4, 6, 5, 3, 1], D: [1, 3, 5, 2, 4, 6], } for name, seq in cases.items(): print(name, can_pop_sequence([1, 2, 3, 4, 5, 6], seq))代码里pushed是入栈顺序固定为 1 到 6popped是待验证的出栈序列j指向当前希望弹出的元素。每压入一个元素就尽可能把栈顶连续弹出循环结束后如果j走到popped末尾说明目标序列能被模拟出来返回 True否则返回 False。运行结果 A、B、C 为 TrueD 为 False和手算结论一致。考场不能运行代码时就在草稿上画一个栈写“入栈/出栈”两列每步只盯栈顶和目标元素不要跳步。4.4 三类题的共同检查模型先行组合题先定人数分配型格雷码先做相邻异或栈题先模拟入栈出栈。三类题都不适合“看选项凭感觉”因为干扰项往往按常见错误设计组合题漏掉某个部门出 2 人格雷码只检查前半段栈题只盯着目标序列的“数字顺序”。做完后分别查三件事分类有没有重复或遗漏相邻异或是否全为 1 位栈模拟是否走到目标末尾。这个检查顺序比重新算一遍更快也更稳定。5. 易错题与失分点五类翻车场景的纠正方式初赛选择题的失分很少是因为完全没学过更多是因为“会一点但动作不稳”。下面五类场景在真题里反复出现每一类都按“错在哪、为什么错、怎么答对”拆开。看的时候不要只看答案重点看错误发生的那一步考场上把这一步拦住分数就能捡回来。5.1 失分点一int 边界差一错在哪把 32 位 int 的范围写成 -2147483647~2147483647或者写成 -2147483648~2147483648。前者左右对称后者两端都多算看起来都很“整齐”所以容易选错。为什么错有符号整数的补码表示里0 占一种编码负数比正数多一种所以最小负数的绝对值比最大正数大 1。通式是 -2^(n-1) 到 2^(n-1)-1左端和右端并不对称。考生如果只记“2 的 31 次方等于 2147483648”很容易把右端也写成这个数忽略最大值要减 1。怎么答对先写通式再代入 n写完检查左端绝对值是否等于右端加 1。如果左右绝对值相等说明最小负数少了一个如果右端等于 2^(n-1)说明最大值多了一个。这个检查动作花不了几秒但能挡住边界题最常见的两个错误选项。5.2 失分点二进制题把下标读丢错在哪把 14₈ 读成一百四十八把 1010₂ 读成一万零一百零二把 D₁₆ 读成 D 乘 16。题面排版一旦把下标压平这些数字看起来就像普通十进制数按十进制算完还对不上选项。为什么错不同进制的数在书写时靠下标区分下标被吃掉后数字本身不会提醒你它是几进制。D 在十六进制里是数字 13不是字母变量1010₂ 是二进制不是十进制的一千零一十。考生如果平时做题只扫一眼数字没有补下标的习惯考场上就会按表面数字硬算。怎么答对读题时先在草稿上给每个数补下标再逐项转十进制转完按原式的括号和运算符顺序算不要改运算顺序。最后回代检查结果是否落在选项里数量级是否合理。进制题的错误大多发生在读题阶段不在计算阶段补下标就是最便宜的后悔药。5.3 失分点三组合计数漏“哪个部门出 2 人”错在哪只算 A 部门出 2 人得到 54 就选 A或者只算 B、C 各出一种情况没有把三类加起来。题目问“有多少种选择方式”答案却停在某一类里。为什么错4 人分到 3 个部门且每个部门至少 1 人人数分配型是 2、1、1但“2 人部门”可以是 A也可以是 B 或 C。只算 A 出 2 人等于默认 A 是唯一可能出 2 人的部门漏掉了另外两类。组合计数的分类标准一旦选错后面算得再细也会漏。怎么答对先写人数分配型再按“哪个部门出 2 人”分类每一类用乘法原理算内部选择最后用加法原理合并。检查时看总数是否大于单一分类如果等于单一分类基本可以判定漏类。题 3 的三类分别是 54、36、36合计 126和选项 B 对上。5.4 失分点四栈题只盯目标序列不模拟入栈指针错在哪看到 135246 这种“奇偶穿插”的序列凭感觉判断“应该可以”没有真正模拟入栈和出栈或者只看出栈数字的大小关系忽略栈顶限制。为什么错出栈序列不是任意排列它受“后进先出”约束。一个元素要出栈必须已经入栈并且位于栈顶如果目标元素还没入栈就不能先出它。只盯着目标序列看很容易把“数字顺序”当成“出栈顺序”忽略中间压了哪些元素。怎么答对手写一个栈按入栈顺序压元素每压一个就看栈顶是不是当前目标是就连续弹出不是就继续压压完所有元素后如果目标指针还没走到末尾这个序列就是不可能的。题 4 的 D 序列在 3 出栈后2 还被压在栈里后面要求先出 2 再出 4、6栈顶关系对不上所以不合法。手算没把握时用 4.3 的模拟代码复核。5.5 失分点五格雷码只看前几位相邻错在哪看到 0000、0001、0011、0010 开头每对都只差一位就认定整个序列是格雷码没有检查最后两对或者只数了相邻码中“变化的那一位”没有确认只变一位。为什么错格雷码要求整个序列的每一对相邻码都只差一位包括最后一对。干扰项经常在前面几对做得和正确序列一样只在末尾换一个码让最后一对差两位或三位。考生如果检查到一半就下结论正好踩进设好的坑。怎么答对逐对异或数结果里 1 的个数每一对都要查尤其是最后一对。题 4 中 A 的最后两对、B 的 0111-0100、C 的 0010-0100 都露出了差异位数不对的问题D 则每一对都只差一位。检查时不要跳对按顺序从头到尾走一遍比凭印象选更稳。6. 考场答题技巧选择题检查顺序与押题思路选择题的答题顺序可以按“稳—快—模拟”来排先做 int 范围、存储单位、语法判断这类动作固定的题拿到确定分再做进制混合运算和组合计数这两类需要草稿但模型清楚最后做格雷码和栈序列因为这两类需要逐对检查或模拟放在后面更不容易被前面的题打断节奏。每道题做完不要立刻涂答案就走留十秒做一次针对性回看。题型第一动作检查点int 范围写 n 位有符号通式左端绝对值是否等于右端加 1进制混合给每个数补下标是否逐项转十、运算符是否看错存储单位画 MB→KB→B→bit 链最后是否乘了 8组合计数先写人数分配型是否按“2 人部门”分全三类格雷码相邻逐对异或最后一对是否也只差一位栈序列手写栈模拟目标指针是否走到末尾押题思路不用铺得太宽把上面六类练到“看到题就知道第一动作”就够了。int 范围、进制混合、存储单位是计算机基础里的常客组合计数偏爱“至少一人”“每个部门都要有”这种分配型格雷码和栈序列则是编码与数据结构的固定题型语法判断通常围绕基本类型和循环语句做排除。复习时不要按题号刷按模型刷同一模型连做几道把检查动作固定下来比散着做题有效。血泪经验是选择题的对错经常不取决于会不会而取决于读题时有没有把下标、边界、分类和栈顶这四个信息留住。从那以后我每次做完选择题都强制走一遍“下标—边界—分类—模拟”四步检查错题旁边只写错因不抄答案。这份试题与答案解析按题号和模块整理适合先遮住答案做一遍再按上面的检查动作对错因拿到后先做再对比直接看解析更有用。希望帮到你。本文还有配套的精品资源点击获取