简介这是2024年海淀区中小学生信息学竞赛校级预选赛试卷面向参赛中小学生及辅导教师可用于考前模拟与知识查漏。试卷由编程基础知识单选题和程序阅读单选题组成前者覆盖变量命名合法性、赋值语句写法、二进制与十进制转换、表达式运算结果、逻辑判断、函数定义与递归、运算符特性、for/while循环及break/continue作用等基础内容后者给出多段C代码要求推断输出结果或变量取值涉及素数判定、约数统计、最大公约数、回文数判断、筛法等经典算法片段适合训练代码阅读与逻辑推演能力也能帮助考生快速定位知识薄弱环节。试题以单个PDF文档形式打包共422KB下载后可直接打印或屏幕阅读。目前已有576人学习使用可作为学生参加海淀区信息学竞赛的针对性练习材料。对希望了解海淀区信息学竞赛命题风格、检验自身编程基础的学生而言这份试卷提供了方便的入门训练入口。1. 海淀区信息学竞赛的校级预选赛一张试卷卡在编程竞赛的入口考驾照得先过科目一坐在电脑前答交规题一道题都不用碰车。海淀区中小学生信息学竞赛的校级预选赛干的就是这件事——它是整条竞赛路的第一道闸门过了它才有资格进区级初赛再往后才是真正上机写代码的复赛。这张试卷有一个鲜明特点几乎全是选择题。它不要求你打开编译器敲出一段能运行的程序而是把编程基础知识和程序片段摆在卷面上让你判断对错、推断输出、算出结果。一句话它考的不是会不会写而是懂不懂。对想走信息学竞赛这条路的学生和家长来说这份试卷值得仔细研究。预选赛的分数直接决定你有没有下一轮的入场券而它的考法和复赛上机完全不同。把这张试卷吃透等于先把竞赛入口处的规则摸清了。2. 为什么要有校级预选赛一场编程竞赛为什么先设笔试关2.1 报名的人太多上机考场装不下海淀区信息学竞赛并非谁都能报名。试卷第一题就点明了报名规则报名在网上报名系统进行必须经过学籍所在学校的指导教师审核。这里的关键词是学籍所在学校——参赛资格和学籍绑定学生在哪里读书就从哪所学校的通道报名。这和社会上的自由报名考级完全不同它天然圈定了参赛范围。但即便有学籍门槛海淀区中小学数量多、编程热度高最终报名人数还是会远超一场上机考试能容纳的量级。上机编程考试要占用机房每个考生一台电脑监考老师要来回走动判题要么靠人工看代码要么靠判题系统比对输出。场地、设备、人力、时间每一项都是成本。校级预选赛把这些成本压到了最低一张纸质试卷、一支笔、一个考场几百名学生同时答题。选择题可以快速核对一天之内就能完成一轮筛选。这和驾照科目一的逻辑一模一样——先用最便宜的方式把完全没摸过车的人筛掉再把宝贵的练车和路考资源留给真正有准备的人。2.2 晋级路径每一层都在换一种考法从报名到最终拿奖海淀区信息学竞赛的流程大致是网上报名系统报名学校指导教师审核资格然后参加校级预选赛达到一定分数晋级区级初赛区级初赛再筛一轮达到分数线进入区级复赛复赛才是真正的上机编程考试。注意每一层的考法都在变化。校级预选赛是笔试考基础知识和阅读代码区级初赛的题型和预选赛类似但难度和分数线要看当年的竞争情况到了复赛直接打开电脑写代码题目通常是完整的算法题需要自己设计数据结构和算法用程序解决问题。这提醒参赛者一个关键信息预选赛的备考方式和复赛完全不同。预选赛重识记和理解复赛重设计和实现。很多学生在预选赛阶段拼命背代码模板结果复赛面对一个没见过的问题直接懵住就是因为没意识到预选赛只是门槛不是终点。2.3 三种题型对应三种能力这套预选赛试卷的大结构很清晰三大题型各有分工。第一大题是编程基础知识单选题像一张语法体检表。它把变量命名规则、赋值语句写法、二进制与十进制的转换、表达式运算结果、逻辑表达式、函数特性、循环语句、二维数组初始化等知识点挨个考一遍。这些内容不涉及复杂算法纯粹看你有没有把 C 的基础规矩记牢。比如它会问合法变量名称是哪个或者把字符串赋值给整型变量为什么错这些都是初学者第一次写代码时最容易踩的坑。第二大题是程序阅读单选题每题给出一小段完整的 C 程序让你推断输入某个整数后的输出。例如有程序用 for 循环统计一个数的约数个数有程序用埃氏筛标记素数有程序用递归求最大公约数还有程序判断回文数。你没法把代码复制到编译器里跑只能在大脑里模拟执行一句一句地推。这考的就是人肉编译器的水平。第三大题是问题阅读单选题也叫应用题。它用大段文字描述现实场景手机桌面上应用程序图标按规则交换位置、视频服务器按上传时间排队压缩视频、多枚异形骰子同时掷出求和、小猴爬山连续多天的海拔变化。题目不给你代码只给你规则和条件你要自己把文字描述翻译成可计算的逻辑模型。这种建模能力恰恰是信息学竞赛复赛上机题的核心考察点。所以说校级预选赛虽然只是科目一但它用三种不同的题型把懂语法、能读码、会建模三个层次的能力一次性测了一遍。通过的人至少说明在思维上已经迈进了编程的门。3. 编程基础知识单选题一场对 C 语法规矩的全面体检3.1 变量命名与赋值起名字的规矩和放东西的方式变量名是程序里给数据起的名字但这个名字不是随便起的。C 的规则是只能以字母或下划线开头后面可以跟字母、数字或下划线不能和关键字重名不能包含空格和标点。int 2x; // 错误不能以数字开头 int _x; // 正确下划线开头合法 int double; // 错误double 是关键字不能用 int x y; // 错误变量名里不能有空格赋值语句的考点同样围绕规矩展开。a 1;是标准赋值把整数 1 放进变量 a 的格子里。而a 1;一定错误——左边是整型变量右边是字符串类型不匹配。容易混淆的是a 1;这个其实是合法的C 里字符 1 会被自动转成它的 ASCII 码值 49然后赋给整型变量 a。所以试卷里问哪个赋值写法一定错误答案通常就是字符串赋值给整型变量那项。另外要分清赋值和比较a 1是赋值a 1是比较。写代码时一个等号和两个等号搞混编译器不会直接报错但程序逻辑会跑偏这种翻车在初学者里太常见了。3.2 进制转换与表达式运算数学功底决定上限二进制转十进制考的是位权展开。比如二进制数 1101从右往左每一位的权重是 1、2、4、8所以 1101 转十进制就是 1×8 1×4 0×2 1×1 13。这套规则是理解计算机内部数据的基础也是不少学生的第一道坎——平时数数都用十进制突然要换一种进制脑子转不过弯。表达式运算题考的是运算符优先级和求值顺序。优先级从高到低大致是逻辑非! 算术运算符 关系运算符 逻辑与 逻辑或||。遇到一个混合表达式先算谁后算谁决定了最终结果是真是假。这里还有一个隐藏考点字符型变量能不能参加算术运算。很多初学者以为 char 是字母不能算数。实际上 C 里 char 的本质是一个 0 到 127 的整数用的是 ASCII 编码。字符 a 的 ASCII 值是 97所以a 1的结果是 98对应字符 b。字符完全可以参加算术运算试卷里字符型变量不能参加算术运算这个说法就是错的。想明白这一点字符和整数之间的转换题就能一眼看穿。3.3 循环与跳转让程序重复做事的三种手段for 和 while 是 C 里最常见的两种循环。试卷里有道题说for 语句能够实现确定次数的循环功能还有一句while 语句专用来实现不确定次数的循环功能。前者是对的后者是错的。为什么错因为 for 和 while 本质上可以互相转换。for 把初始化、循环条件、步进写在一行适合数着次数的计数循环while 只写循环条件适合等到某个状态发生的场景。但适合不代表只能。用 while 完全能写确定次数的循环用 for 也完全可以写不确定次数的循环只是写起来别扭而已。把风格偏好说成功能限制就是这道题的陷阱。循环里还有两个跳转语句需要分清。break 是彻底跳出整个循环循环直接结束continue 是跳过本次循环的剩余语句回到循环条件判断开始下一轮。打个比方break 是直接踢门出去continue 是这轮不干了、下轮接着排队。考试里这两句话经常一字之差读错一个词整个程序的执行过程就全变了。3.4 函数与数组模块化和数据箱子函数部分考的是基本特性每个程序有且只有一个主函数主函数是程序执行的入口函数可以自己调用自己这就是递归递归函数就是函数自己调用自己的典型代表。这里最容易混的是嵌套这两个字。C 里函数定义不能嵌套——你不能在一个函数里面再完整地定义另一个函数但函数调用可以嵌套一个函数调用另一个函数调来调去都合法。试卷里函数不支持嵌套这个说法之所以是错的就是因为它把不能嵌套定义和不能嵌套调用混为一谈。二维数组是另一个高频考点。int a[3][2] {2,3,4,5,6,7};表示一个 3 行 2 列的二维数组初始化数据按行填充下标列0列1行0a[0][0]2a[0][1]3行1a[1][0]4a[1][1]5行2a[2][0]6a[2][1]7C 数组下标一律从 0 开始这是最容易翻车的地方。a[1][1] 对应的是第 2 行第 2 列值是 5而 a[2][2] 已经越界了——数组只有 0、1、2 三行每行只有 0、1 两列a[2][2] 根本不存在。题目就是抓这种看着顺眼、实际越界的陷阱。4. 程序阅读题在脑子里运行一遍代码的能力4.1 人肉编译器用一张纸追踪变量程序阅读题没有捷径核心方法就一个拿一个具体输入逐行执行代码用纸笔记录每个变量的变化。这不是玄学而是实打实的人肉模拟执行。以试卷里的约数计数题为例int n, cnt 0; cin n; for(int i 1; i n; i) { if(n % i 0) cnt; } cout cnt;这个程序统计小于 n 的约数个数。输入 n 10循环从 i 1 跑到 i 9。10 能被 1、2、5 整除所以 cnt 最终是 3。注意循环条件是i n而不是i n因此 10 本身不会被统计。如果条件改成i n答案就变成 4。一个小于号的差别输出完全不一样。这就是程序阅读题的本质把代码当成一份操作说明书在人脑里一步步执行。变量就是便签纸上的格子循环就是反复执行同一段操作函数调用就是跳到另一份说明书再跳回来。提示程序阅读题追求一次算对而不是算快。宁可多花两分钟在草稿纸上画变量表也别凭感觉选答案。4.2 高频算法原型筛法、递归、回文这套试卷的程序阅读题表面上是四五个独立的小程序实际上反复在考几个经典算法原型。认识这些原型读题速度会快很多。埃氏筛素数筛int n, a[10010]; cin n; a[1] 1; // 1 不是素数先标记 for(int i 2; i 10000; i) { if(a[i] ! 0) continue; // 已经被标记过就跳过 for(int j 2; j 10000 / i; j) { a[i * j] 1; // 把 i 的倍数标记为合数 } }这段代码里a[i] 等于 0 表示 i 是素数等于 1 表示合数。外层循环找到第一个没被标记的数它就是素数内层循环把它所有的倍数都标记成合数。筛法的时间复杂度接近线性是信息学竞赛入门必会的内容。求最大公约数的递归版本int f(int a, int b) { if(b 0) return a; return f(b, a % b); // 辗转相除 }这就是欧几里得算法。只要 b 不是 0就用 a 对 b 取模然后递归调用。当 b 变成 0 时a 就是最大公约数。这段代码短但信息量大它同时考了递归、取模运算、函数返回值三个知识点。回文数判断bool f(int x) { int s 0, t x; while(t ! 0) { s s * 10 (t % 10); // 取出个位拼到结果末尾 t / 10; // 去掉个位 } return (s x); // 倒过来相等就是回文数 }核心是s s * 10 (t % 10)这一句每次从原数末尾取出一个数字拼到新数的末尾。整个过程就是把数字倒过来写。循环结束之后比较 s 和 x相等说明是回文数。这个数字反转的写法在很多题目里都会出现。4.3 分支逻辑题素性判断与哥德巴赫猜想试卷里有一道程序用到了一个经典数论逻辑。它先判断输入的数是不是素数然后根据情况输出 1、2 或 3bool f(int x) { for(int i 2; i * i x; i) { if(x % i 0) return 0; // 找到约数不是素数 } return 1; // 没找到约数是素数 }这里i * i x是一个重要的优化判断素数只需要试到平方根就够了因为如果 x 有一个大于平方根的因子那它一定对应一个小于平方根的因子。这个优化在竞赛里几乎必考。接下来的分支逻辑是如果 n 是素数输出 1否则如果 n 是偶数输出 2否则如果 n-2 是素数输出 2否则输出 3。这实际上是简化版的哥德巴赫猜想——任何一个大于 2 的偶数都可以表示成两个素数之和。程序用穷举的方式判断 n 能不能拆成两个素数的和。读懂这个逻辑比单纯算出答案更有价值因为它训练的是把数学猜想翻译成程序判断的思维。4.4 长文本应用题把中文规则翻译成逻辑模型第三大题的问题阅读题不给代码只给一大段文字描述这种题的难点不在编程而在翻译。比如手机操作系统那道题描述了应用程序图标在屏幕上如何排列、启动后如何与前一个图标交换位置。题目特别强调了一句注意区分应用程序的编号以及位置这是两个不同的变量。这句话就是全题的题眼——很多人翻车就是因为把编号和位置当成一回事一交换就全乱套。再比如视频压缩问题若干台服务器按视频上传时间依次压缩每台每秒压缩一分钟时长的视频同一时间一台服务器只能处理一个视频视频到了有服务器空闲就立即开始。这类题本质上是在考排队论的模拟——把时间轴画出来一台服务器一条时间线把每个视频的到达时刻和压缩时长标上去一个格子一个格子地推。这类题的通用做法是三步第一步圈出题目里的所有名词和规则第二步把规则写成如果……那么……的条件句第三步拿题目给的具体数据代入按时间顺序或操作顺序一步步推演。把文字翻译成逻辑模型的能力正是复赛上机时设计算法的前身。5. 常见误区与易混概念新手最容易翻车的几个点5.1 变量名看着像单词不代表合法易混点_x、2x、x y到底哪个是合法变量名为什么混很多人觉得名字只要读起来像变量就行忽略了语法规则。怎么区分记住三条硬规矩——开头只能是字母或下划线不能是数字不能和关键字重名名字中间不能有空格。只要违反其中任何一条编译器直接报错。考试不会考冷门规则翻来覆去就是这三条。5.2 break 和 continue一个跳出一个跳过易混点break 和 continue 都写在循环体里都能影响循环流程好像都打断了循环。为什么混它们的中文翻译都有中断的意思初学者容易当成一回事。怎么区分break 是立刻结束整个循环跳出循环体继续执行循环后面的代码continue 是结束本次循环的当前轮次跳过本轮剩余语句回到循环条件判断开始下一轮。一句话break 是退场continue 是跳轮。5.3 数组下标从 0 开始是规矩中的规矩易混点int a[3][2]里a[1][1] 到底是第几个元素为什么混日常生活数数从 1 开始第一个第二个顺口得很程序里却从 0 开始。怎么区分C 数组下标一律从 0 开始。a[3][2] 是 3 行 2 列下标范围从 a[0][0] 到 a[2][1]。初始化{2,3,4,5,6,7}按行填充所以 a[1][1] 的值是 5。更阴险的是 a[2][2]——看着下标 2 很合理其实已经越界这是考试最爱挖的坑。5.4 字符型变量1 和 1 不是一回事易混点字符 1 和整数 1 长得几乎一样能不能互换使用为什么混在屏幕上打印出来都是字符 1容易觉得它们相等。怎么区分1 是字符在内存里存的是它的 ASCII 码值 491 是整数存的就是数字 1。两者相差 48运算结果完全不同。反过来字符型变量是完全可以参加算术运算的——它本质就是 0 到 127 的整数a 1 等于 98对应字符 b。把字符当整数用是 C 里一个容易忽略又极其重要的特性。5.5 循环边界i n 和 i n 的差别易混点统计约数时n 本身算不算约数为什么混数学课上学过一个数的约数包含它自己比如 10 的约数有 1、2、5、10 共 4 个。程序里写i n就只有 3 个。怎么区分看循环条件用的是还是。程序阅读题最阴的地方就在这类边界一个符号的差别答案就从 3 变成 4。动手数几个数再下结论比盯着代码发呆可靠。6. 这份试卷什么时候用从备赛到日常的边界判断6.1 适合用在哪第一备赛摸底。比赛前一到两个月限时做一遍这份试卷然后看丢分分布语法题丢分多回去补基础规则程序阅读丢分多专门练脑内模拟执行应用题丢分多练文字转逻辑模型的翻译。一套试卷测出三个板块的薄弱点比盲目刷题高效得多。第二知识点自测。学完变量、循环、数组、函数这几个单元之后拿它当阶段性测验。这份试卷覆盖的知识面和信息学竞赛入门教学大纲高度重合哪一章没学透做一遍就现原形。第三教师参考。负责组织校级预选赛的老师可以直接参考这套题的题型分布、难度梯度和考察方式省去从零设计试卷的时间。6.2 不适合用在哪第一零基础系统学习。这份试卷是体检不是教材。完全不懂编程的人做它只会受挫它没有讲解只有判断对错学不到新知识。第二复赛冲刺。预选赛是选择题复赛是上机写代码两者技能要求不同。已经进入复赛备考的学生应该去刷需要自己写完整程序的题目而不是反复做这份笔试卷。第三算法深度训练。试卷里的算法都是经典原型属于入门难度。想挑战更高阶的数据结构或动态规划需要另找专项资料。预选赛和复赛的定位差异可以看这张表维度校级预选赛区级复赛形式笔试选择题上机编程考点语法、读码、建模算法设计与实现核心能力理解和推断设计和调试备考方式背规则、练阅读刷题、调错、积累套路带 A 同学备赛那一年我让他先做了一遍这份预选赛试卷当摸底。他丢分最狠的不是语法而是程序阅读——一看到 for 循环就晕变量一多就乱。我们花了一周时间专门练脑内模拟把每个变量画成表格一行代码一行代码地推硬生生把阅读正确率提了上来后来他顺利过了预选赛。从那以后我带每个学生备赛都强制先来一遍这样的笔试摸底先把问题找准再谈其他。希望帮到你。本文还有配套的精品资源点击获取
阅读完成 · 觉得有帮助?