CSP-J的第一轮认证,也就是大家常说的初赛笔试,每年都能劝退一波人。很多同学在暑假把C++语法学得滚瓜烂熟,结果一到初赛,面对那些“计算机基础知识”“进制转换”“程序阅读题”照样发懵。其实这轮笔试压根不考你写代码的能力,考的是“常识+逻辑+细心”。只要把知识体系梳理清楚,配合合适的刷题策略,通过线并不难。
这篇东西不是给你罗列考纲,而是把我自己备考和带学生过程中踩过的坑、总结出来的重点一次说透。从题型分值到知识板块,从程序阅读题的破解思路到考场上如何分配时间,全部按实操来写。不管你是刚接触信息学的零基础,还是已经学了一两年但初赛总飘的选手,都能从中找到能直接用的东西。
1. CSP-J第一轮到底考什么?先搞懂游戏规则
1.1 题型分布与分值
CSP-J第一轮认证采用笔试形式,满分100分,考试时间一般是两个小时。虽然各省分数线不一样,但通常稳定在30到50分之间就能进入第二轮,个别强省可能需要60分以上。这个分数要求决定了我们的备考策略:不需要面面俱到,但基础分必须全拿到。
题型只有三大类:
- 单项选择题:共15题,每题2分,合计30分。这部分考的是基础知识点,题目直接,会就是会,不会就靠蒙。
- 阅读程序题:共3大题,每个大题包含若干小题,合计40分。每道大题给一段C++程序,让你读代码、判断输出或者判断说法的正误。这部分是拉开差距的关键。
- 完善程序题:共2大题,合计30分。给你一段不完整的程序,在空缺处选择正确代码。
从分值占比就能看出来,程序题占了70分。所以“程序阅读能力”才是第一轮笔试的核心,纯粹的计算机常识记忆题只有30分左右。很多同学把时间花在背各种奇怪硬件术语上,反而忽略了读代码能力的训练,这是本末倒置。
1.2 知识板块拆解
如果把近三年的初赛真题按知识点分类,大致可以分成这几个板块:
- 计算机基础与历史:包括计算机硬件组成、操作系统基础、软件分类、字符编码等。大概占8到10分。
- 进制转换与位运算:二进制、八进制、十六进制之间的转换,与、或、异或、左移右移等位运算。大概占6到8分。
- 数据结构与算法基础:栈、队列、链表、树、图的基本概念,排序算法复杂度,二分、贪心、动态规划等算法的基本思想。大概占6到8分。
- 数学基础与逻辑推理:排列组合、概率、数论基础、逻辑表达式化简、集合运算。大概占4到6分。
- 阅读程序与完善程序:这两部分其实覆盖了上面所有知识点,尤其是数组、循环、递归、函数调用这些编程基本功。占70分。
从这个分布能看出一个规律:纯记忆类的内容占比并不高,大部分分数要靠“理解程序逻辑”来拿。所以备考时不要一上来就抱着各种资料通读,先搞清楚自己哪块薄弱,再针对性补。
2. 基础知识重点清单:这些分不能丢
2.1 计算机常识与硬件:不用死背,但要懂原理
这块是很多同学认为最枯燥的部分,其实只要理解了计算机是怎么工作的,题目就很好答。比如常考的“冯·诺依曼体系结构”,核心就是“存储程序”思想:程序和数据都放在内存里,CPU从内存取指令一条条执行。这个概念会衍生出CPU由运算器和控制器组成、内存分RAM和ROM、外存有硬盘和U盘等考点。
另一个热点是“信息的表示”。字符编码常考ASCII码,要记住大写字母A是65,小写字母a是97,差32。汉字编码常考GBK和Unicode的区别。这些数字不需要多,记住关键的几个就能推导出其他。
操作系统也是常客。进程和线程的区别、死锁产生的四个必要条件、常见操作系统类型(Windows、Linux、Android),这些都只需要理解概念,不需要深入。我常常用一句话帮学生记:进程是资源分配的最小单位,线程是CPU调度的最小单位。至于死锁,就是两个人各拿一把钥匙还等着对方开门,谁也走不了。
2.2 进制转换与位运算:送分题,必须满分
进制转换是初赛必考,而且几乎是纯送分。二进制、八进制、十进制、十六进制之间的转换,看起来五花八门,其实核心方法就一个:按权展开法。
比如给你一个十六进制数3F,转到十进制就是3乘16的1次方加上F(15)乘16的0次方,等于48加15,得到63。反过来,十进制转二进制就是不断除以2取余数,倒序排列。这些方法在草稿纸上就能写,不需要计算器。
位运算这块,要掌握“与、或、异或、取反、左移、右移”的运算规则。最容易记混的是异或:相同为0、不同为1。左移一位相当于乘以2,右移一位相当于除以2向下取整。题目往往会把位运算和进制转换结合起来,比如“二进制数101101左移两位后等于多少,再转成十六进制”。这种题只要你肯在草稿纸上老老实实算,就一定不会错。
2.3 数据结构与算法基础:概念是根,复杂度是魂
数据结构部分常考的概念有:栈的“后进先出”,队列的“先进先出”,链表相比数组的优势在于插入删除不需要移动元素,但随机访问效率低。树这块要会算结点数,知道二叉树第i层最多有2的(i-1)次方个结点,深度为h的二叉树最多有2的h次方减1个结点。图的部分了解有向图、无向图、邻接矩阵和邻接表就够了。
算法部分最常考的是排序算法的时间复杂度。教材上说过很多次,我再帮大家整理一遍:
| 排序算法 | 平均时间复杂度 | 稳定性 | 记忆要点 |
|---|---|---|---|
| 冒泡排序 | O(n²) | 稳定 | 相邻交换 |
| 选择排序 | O(n²) | 不稳定 | 选最小放前面 |
| 插入排序 | O(n²) | 稳定 | 像打扑克插牌 |
| 快速排序 | O(n log n) | 不稳定 | 分治,选基准 |
| 归并排序 | O(n log n) | 稳定 | 分治,合并有序序列 |
| 堆排序 | O(n log n) | 不稳定 | 利用堆结构 |
初赛不会让你手写排序,但会问某种排序在某些情况下是否稳定、最优时间是多少。另外要理解顺序查找是O(n),二分查找要求数据有序且存储方式支持随机访问,所以数组可以,链表不行。
2.4 计算机网络与操作系统:记住经典模型和协议
网络部分每年都会出个一两题。基础中的基础是OSI七层模型和TCP/IP四层模型。初赛更爱考的是TCP/IP模型,你得知道应用层有HTTP、FTP、DNS,传输层有TCP和UDP,网络层有IP和ICMP。TCP是有连接的可靠传输,UDP是无连接的不可靠传输,这个对比是最常见的考点。
另外一个高频考点是IP地址分类。IPv4地址由网络号和主机号组成,A类地址范围是1.0.0.0到127.255.255.255,B类是128到191,C类是192到223。子网掩码的作用就是区分网络号和主机号。这块不需要深入,但一定要知道私有地址段,比如192.168开头的就是私有地址。
操作系统里有一类题常被忽略:进程状态转换。就绪、运行、阻塞三个状态之间的转换,比如从运行到等待是进程主动等待I/O,从阻塞到就绪是I/O完成。这种题只要画个状态图就一目了然。
2.5 数学基础与逻辑推理:小学奥数内容的高配版
数学知识在初赛中占比不小,而且是很多程序题背后的原理。排列组合是最常考的,比如“从5个不同元素中选3个排列有多少种”“从n个元素中选2个组合有多少种”。要熟练区分排列(有序)和组合(无序)。
逻辑表达式也是必考。给你一个“与或非”组成的表达式,让你化简或者求值。这里要记住运算优先级:非最高,与其次,或最低。遇到不清楚的就在草稿纸上列真值表,一分都不会丢。
概率题偶尔会考。比如“掷两个骰子,点数之和为7的概率是多少”,其实就是枚举所有可能结果,算式找出6种满足条件的,总数36种,所以概率是1/6。这部分如果不会,建议补一补古典概型的计算,因为阅读程序题中也经常出现涉及概率的模拟。
3. 程序阅读题的破解思路:拿高分的关键
3.1 模拟执行法:老老实实画表格
阅读程序题给的都是C++代码,长度一般在20到40行之间。很多同学一看到代码就开始在脑子里空转,结果转着转着就乱了。最稳妥的方法是在草稿纸上画一个“变量表”,每执行一行,就把变化过的变量值记录下来。
比如遇到一个for循环,先列出循环变量的初值、条件、步长,然后逐轮模拟。如果循环次数太多,就找规律,看看有没有循环不变量。我有个学生做这类题特别稳,他的习惯是用“列框架”代替“记口头语”:先圈出每个变量的初始值,再画出数组的格子,遇到递归就往右边扩展一张新表。这个习惯一开始会慢,但练熟之后准确率极高。
还有一种方法是“先看整体,再看局部”。读完题目先判断这段程序在干什么:是求最大公约数?是模拟某个数学变换?是在排序?一旦猜到目的,很多小题的答案就能直接推导出来,不需要逐行模拟。比如看到两个变量互相取余,八成是在做辗转相除法;看到swap交换和比较,八成是排序或找最值。
3.2 常见陷阱:浮点数比较、边界条件、数组越界
程序阅读题最爱挖的坑有三个。第一个是浮点数不能直接用“==”比较,因为精度问题。如果代码里出现浮点运算后判断相等,大概率陷阱就在这里。
第二个是边界条件。比如循环条件是i < n还是i <= n,这直接决定执行次数;数组下标从0开始还是从1开始,也经常让粗心的人算错。模拟的时候一定要看清每个等号和不等号。
第三个是运算符优先级。这里的优先级指的是C++中的算术、关系、逻辑运算符混在一起时谁先算。比如a < b && c > d || e,要知道&&的优先级高于||,还要知道关系运算符<的优先级高于逻辑运算符。遇到表达式特别复杂时,别凭感觉,直接按优先级从左到右拆开算。
另外,完善程序题虽然是填空,但考察方式类似阅读题。做这类题时我建议先通读整个程序,搞清楚变量名代表的含义,再看空缺的上下文。选项之间往往差异极小,要特别小心是“i”还是“i-1”、是“<”还是“<=”。这类的分拿下来,整张卷子就已经赢了一大半。
4. 实操备考路线:从零开始怎么准备
4.1 根据基础分三种情况,确定不同节奏
如果你是零基础,还没怎么学过编程,我建议至少提前三个月开始备考。前一个月主攻计算机基础、进制转换、逻辑表达式这些纯知识性的内容,同时开始学C++语法基础。第二个月进入程序阅读训练,每天读两三段代码,先手抄一遍,再逐行解释每部分的用途。第三个月集中刷真题,查漏补缺。
如果你已经学过程序设计,但初赛没考过,那重点就放在真题和模拟题上。拿近五年的真题,每套掐时间做,做完了不要急着对答案,先自己复盘错题。程序题如果错了,一定要在电脑上把代码跑一遍,看看自己漏在哪一步。
如果你只是想在考试前临时突击一周,也不是完全没救。先把选择题的高频考点过一遍,特别是进制转换、位运算、排序复杂度,这些短期记忆效果很好。程序阅读题就练一个“画表模拟”的能力,哪怕代码没完全看懂,只要能准确模拟几步,往往也能蒙对一两个小题。
4.2 刷题与资料选择:真题大于一切
市面上的信息学资料五花八门,但最核心的永远是官方真题。过往年的CSP-J初赛真题,建议大家按年份倒序做。第一次做可以开卷,把不会的知识点查清楚;第二次做要闭卷,模拟真实考试;第三次做只做错题,确保每一道都吃透。
除了真题,也可以找一些专门的“初赛刷题网站”或者“知识点专栏”,但一定要学会甄别。我见过不少同学花大量时间看“汇编语言”“计算机体系结构”的进阶内容,其实初赛根本考不到那个深度。我们的目标是过线,不是拿满分,所以复习要讲究性价比。
我还推荐一种“错题分类法”:准备一个本子,把做错的题按“知识性错误”“计算性错误”“读题错误”“代码理解错误”四类整理。比如你不知道ASCII码大写字母是65,这是知识性错误;你把二进制1101算成了12,这是计算性错误;你把题目要求的“输出第几行”看成了“输出所有行”,这是读题错误。分类之后你会发现,真正需要补的知识点并没有想象中那么多。
5. 常见问题与排查技巧实录
5.1 考场上最容易犯的错:不是不会,是不细心
我监考或陪考过多次CSP-J,发现很多孩子不是知识储备不够,而是考场上手忙脚乱。第一个常见问题是时间分配失衡。选择题遇到一两道不会的,死磕十分钟,导致后面程序题没时间做。正确的策略是:选择题平均每题不超过一分钟,卡住了先凭第一印象选一个,标记出来,最后检查时再想。程序阅读题才是重心,要留足90分钟。
第二个问题是草稿纸用得太乱。到处乱写,算到一半找不到之前的记录,只能重算。建议草稿纸分区使用,一块专门算进制转换,一块专门画程序执行表,一块专门列公式。这样检查时也能快速定位。
第三个问题是做完不检查。初赛的时间通常够用,做完后至少能剩二十分钟。检查的重点不是重算一遍所有题,而是检查:有没有涂错答题卡(虽然是笔试机读卡,但也要注意题号)、程序阅读题的“判断正误”类题目有没有看反“正确”和“错误”的选项、选择题有没有把“不属于”看成“属于”。这些低级错误每年都在发生。
5.2 遇到完全看不懂的代码怎么办
有些阅读程序题的代码会在里面嵌入递归、函数指针、结构体,甚至一些冷门的位操作。看到这种题先别慌,记住一个原则:看不懂的代码也可以拿分。因为程序阅读题的小题往往有多个,有些是问“程序输出的第一行是什么”,有些是问你“下列说法错误的是”。即使你不完全理解整体逻辑,也可以通过模拟前几步,排除掉明显错误的选项。
如果实在模拟不下去,就用“猜答案法”:先看变量名和函数名有没有提示。比如函数叫gcd,大概率是求最大公约数;叫isPrime,一定是在判素数。猜完之后,用特殊值法检验,比如把n=1或者n=2直接代入一个选项,看是否符合认知。我曾经给一个学生演示过,遇到一道关于二叉树遍历的程序题,他完全没看懂核心递归,但通过题目给出的输入样例,硬是把输出推出来了一半。所以永远不要放弃任何一题。
6. 备考过程中的一点心得
我带过不少学生,发现一个有意思的现象:那些初赛考得好的人,往往不是编程最强的人,而是“爱在草稿纸上写写画画”的人。我见过编程拿过省奖的孩子,因为轻敌,觉得初赛笔试就是走个过场,结果在进制转换上栽了跟头。反倒是那些老老实实把每次模拟都当成正式考试的同学,稳稳过线。
说到底,CSP-J第一轮考的不是天赋,而是“刻意练习”的积累。每天花二十分钟做几道进制转换,读一段代码,记录一个错题,坚持一个月,效果远胜于临考前突击一天。如果你能把这里提到的知识清单和答题策略真正用起来,过线只是时间问题。等进了第二轮,再全力以赴拼算法吧。