news 2026/10/31 3:40:41

信息学竞赛PDF刷题:程序阅读与长题干建模训练

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
信息学竞赛PDF刷题:程序阅读与长题干建模训练

简介:这份2024年海淀区中小学生信息学竞赛校级预选赛试题,面向准备参加信息学竞赛的中小学生及带队指导教师,用于赛前自测与知识点查漏补缺。试卷分为编程基础知识单选题和程序阅读单选题两部分:前者覆盖变量命名规则、赋值语句正误、数据类型、二进制与十进制转换、表达式运算、逻辑判断、函数定义与调用、循环语句及二维数组元素定位;后者给出完整C++代码片段,要求推断取余计数、最大公约数、回文数统计、素数筛法等程序的输出结果,侧重代码阅读与逻辑推演能力。资源包共1个PDF文件,约422KB,下载后可直接打印或在线练习。已有588人学习,适合作为校级预选赛模拟卷,帮助考生熟悉题型、检验基础概念掌握程度,并训练按程序执行过程逐步推导答案的习惯。

1. 从一份校级预选赛 PDF 说起:它到底适合谁刷、刷到什么程度

一份 2024 年区级中小学生信息学竞赛校级预选赛试题 PDF,乍看像“低龄语法卷”,真正拉开差距的却是程序阅读和长题干建模。它把编程基础知识单选题、程序阅读单选题、问题阅读单选题放在同一张卷子里,考的不是背概念,而是能不能在有限时间里把变量、循环边界、状态变化和输入范围读准。适合三类人:准备校级预选赛的学生、带竞赛入门的老师、想补代码阅读基本功的初学者。不适合想刷复杂算法模板的进阶选手。它解决的是“语法会一点、读程序就发懵、长题干抓不住条件”的典型问题。

2. 拆开三类题型:从语法细节到长题干建模的刷题顺序

2.1 编程基础知识单选题:语法细节与概念边界

基础知识题看起来最像“送分题”,实际最容易因为概念边界不清丢分。试题里出现了变量命名、赋值语句写法、二进制转十进制、表达式运算结果、函数调用、循环语句、数组下标等内容。这些点单独看都不难,但命题人喜欢在“合法/一定错误/不正确/错误的是”这些限定词上做文章。刷这类题,不能只判断“大概对不对”,要把每个选项为什么错写出来。

我一般会让学生先做一张知识点归因表,不按题号归因,按错因归因。比如变量命名错,是错在首字符、关键字、长度还是大小写;赋值语句错,是错在分号、引号、类型不匹配还是表达式缺右值;二进制转换错,是权位加错还是把二进制当十进制读。归因表比抄答案有用,因为下一套卷子还会换皮考同一个点。

知识点常见考法高频错因训练动作
变量命名判断合法变量名首字符用数字、撞关键字、混入符号每题写出“首字符+字符集+关键字”三项检查
赋值语句判断一定错误的写法把分号、引号、空字符串混进赋值把每个选项改写成合法形式再对照
进制转换二进制转十进制权位从 0 开始数错手写 2 的幂次表,逐位相加
表达式运算判断结果类型和值关系表达式、赋值表达式、逻辑表达式混淆先标类型,再算值
函数与递归判断函数特性把“可以嵌套调用”和“可以嵌套定义”混为一谈用一句话复述每个选项的反例
循环语句判断 for/while/break/continue把“确定次数”和“不确定次数”绝对化给每个循环写一个最小反例

这类题的可执行步骤很固定:第一遍限时做,第二遍只改错题,第三遍把错题选项改写成正确表述。限时建议 30 秒一题,超过 30 秒说明概念不熟,先标记再回看。第二遍不要只看正确答案,要把错误选项的“错点词”圈出来,例如“必须”“只有”“都可以”“一定”。第三遍用一张 A4 纸写“如果我是出题人,下一题会怎么挖坑”,这个动作对校级预选赛特别有效,因为题型重复率高,坑位也相似。

提示:基础知识题不要追求刷题量,先把错因标签打到能复述。标签越细,后面程序阅读题越不容易把语法问题误判成逻辑问题。

2.2 程序阅读单选题:把代码当黑匣子做输入输出推演

程序阅读题是这份试题里最值得动手复现的部分。题目给了若干段 C++ 程序,包括统计约数个数、求两个数的最大公约数并输出最小公倍数、判断回文数、筛法后做前缀统计、判断一个数能否拆成两个质数、递归求 gcd、循环找第一个有 6 个因子的数等。这些程序都不长,但阅读时容易在三个地方翻车:循环边界是<还是<=,break和continue影响哪一层,变量初值和自增位置有没有看漏。

读这类题,我习惯用“黑匣子三列法”。第一列写输入假设,第二列写每轮循环后的关键变量,第三列写输出。不要一上来推整个程序,先找变量职责:cnt是计数还是累加,ans是答案还是临时值,a数组是标记数组还是前缀数组。职责找对,推演速度会快很多。

以试题中“统计约数个数”的程序为例,核心逻辑是for(int i=1;i<n;i++) if(n%i==0) cnt++;。它统计的是小于n的约数个数,不包含n本身。如果输入是 6,约数有 1、2、3、6,但循环只到 5,所以cnt是 3。很多同学会按“约数个数”直接选 4,这就是把“变量名语义”当成了“程序语义”。程序阅读题永远以代码为准,不以题面词语为准。

再比如求最小公倍数的程序,先用c=min(a,b)从较小值往下找最大公约数,找到后break,最后输出a*b/d。这里d是最大公约数,输出的是最小公倍数。读的时候要盯住d的更新位置:它在if(a%i==0 && b%i==0)里面被赋值为i,然后立刻break,所以d保存的是从大到小找到的第一个公约数,也就是最大公约数。如果break看漏,就会误以为d会被覆盖成最小公约数。

程序阅读题的可执行训练步骤可以拆成四步:

  1. 先标变量职责,不急着算数。
  2. 用最小输入手推一轮,确认循环边界。
  3. 再换一个能触发break或continue的输入,观察分支走向。
  4. 最后把程序敲进本地环境跑一遍,对照手推结果。

第 4 步很关键。纸面推演容易自我说服,本地跑一遍能看到真实输出。常见做法是建一个read_program/目录,每道题一个.cpp文件,输入用重定向,输出贴回错题表。这样错题表里不只有“答案是 B”,还有“我推出来是 C,程序跑出来是 B,差在i<n还是i<=n”。

2.3 问题阅读单选题:长题干建模与边界条件提取

第三类题是长题干单选题,包括手机菜单图标滚动、服务器压缩视频、掷骰子求和、小猴爬山记录等。这类题题干长、变量多,很多学生读完第一遍只记住“有个手机”“有个服务器”,做题时凭感觉选。实际它考的是建模顺序:先分清变量角色,再找状态变化规则,最后检查边界。

手机菜单题的关键是“应用编号”和“图标位置”是两个变量。题目给的是初始位置排列,启动的是应用编号,启动后还要交换图标位置。读题时先写两个数组:pos[app]表示应用当前在哪,at[position]表示某个位置上是哪个应用。每次启动先算滚动次数,再算双击的 1 次操作,然后按规则交换。滚动次数不是按应用编号算,而是按当前位置算。这个区分不写清楚,后面全错。

视频压缩题的关键是时间线。服务器按上传顺序取视频,每个服务器有压缩速率,视频长度不同,完成时间取“到达时间”和“服务器空闲时间”的较大值,再加上压缩耗时。题干里单位容易混:秒、分钟、视频长度、服务器速率。我一般要求先统一单位,再列表。表格列固定为:视频编号、上传时间、长度、分配服务器、开始时间、完成时间。列一拉出来,错误选项就很容易排除。

骰子题和爬山题考的是约束范围。骰子题给每个骰子的面数,问哪些数字可能出现,核心是“固定某个骰子取某个值后,剩余骰子的和是否落在最小值和最大值之间”。爬山题给起点、终点和相邻两天海拔差限制,问可能最高海拔,核心是从左到右推可达上界,再从右到左推可达上界,最后取两者较小值。长题干题不要一上来算答案,先把“变量表”和“约束表”写出来,再动笔。

题型核心变量状态变化边界检查
手机菜单应用编号、图标位置、每屏容量启动后交换当前位置与前一个位置位置为 1 时不交换;最后一屏可能不满
视频压缩服务器数、视频数、上传时间、视频长度服务器空闲即取队首视频同一秒多个视频到达;单位统一
骰子求和骰子数、面数、目标和固定一个面后检查剩余和区间每个骰子最小值 1,最大值是面数
小猴爬山天数、起点、终点、相邻差限制从左推上界,从右推上界起点终点固定;相邻差不超过给定值

3. 把程序阅读题跑起来:本地复现环境与批量对照脚本

3.1 编译环境与最小目录结构

这份 PDF 是试题文档,不是源码包,所以复现重点不是“安装某个框架”,而是把题目里的程序片段变成可编译、可对照的最小工程。常见做法是建一个平铺目录,每道程序阅读题一个源文件,输入输出用文本文件保存。编译器用常见的 C++ 环境即可,标准选 C++17 就够,题目里的语法没有更特殊的要求。

mkdir -p contest_pdf/{src,cases,out,notes} cd contest_pdf touch src/p01_divisor_cnt.cpp touch src/p02_gcd_lcm.cpp touch src/p03_palindrome_cnt.cpp touch cases/p01.in cases/p01.expected touch cases/p02.in cases/p02.expected

这段命令只做三件事:建目录、建源文件、建用例文件。src/放题目程序,cases/放输入和期望输出,out/放实际输出,notes/放错题表。参数上不需要花哨命名,题号加语义就够了,比如p01_divisor_cnt表示第 1 题约数计数。目录越简单,后面批量脚本越好写。

注意:不要把所有题目塞进一个main.cpp。程序阅读题之间变量名和逻辑容易串,分开文件才能单独编译、单独对照。

3.2 用 C++ 复现题目程序并做输入输出对照

以试题中“统计小于 n 的约数个数”和“求最大公约数后输出最小公倍数”两段程序为例,复现时不要改题目逻辑,只补头文件和输入输出。这样跑出来的结果才能和卷面答案对照。下面这段代码把两个程序放在不同命名空间里,避免main冲突,实际训练时也可以拆成两个文件。

#include <iostream> #include <algorithm> using namespace std; namespace p01 { int n, cnt; void solve() { cin >> n; // 题目循环到 i < n,统计的是小于 n 的约数个数 for (int i = 1; i < n; i++) { if (n % i == 0) cnt++; } cout << cnt << endl; } } namespace p02 { int a, b, c, d; void solve() { cin >> a >> b; c = min(a, b); // 从较小值往下找,找到的第一个公约数就是最大公约数 for (int i = c; i > 0; i--) { if (a % i == 0 && b % i == 0) { d = i; break; } } // d 是最大公约数,a*b/d 是最小公倍数 cout << a * b / d << endl; } } int main() { int task; cin >> task; if (task == 1) p01::solve(); else p02::solve(); return 0; }

代码里保留了两个题目的原始循环边界。p01的i < n是易错点,改成i <= n就会把n本身算进去。p02的break也是易错点,去掉后d会被覆盖成 1 或其他公约数。参数说明:task只用于选择跑哪道题,不参与题目逻辑;n、a、b来自输入文件;cnt、d是全局变量,初值为 0,这一点和卷面程序一致。编译时用g++ -std=c++17 -O2 -o out/run src/p01_divisor_cnt.cpp这类命令即可,-O2不影响结果,只是让批量跑更快。

跑用例时建议用重定向,不要手工敲输入:

echo "1 6" | ./out/run echo "2 12 18" | ./out/run

第一行输出 3,因为小于 6 的约数是 1、2、3;第二行输出 36,因为 12 和 18 的最大公约数是 6,最小公倍数是 36。把这两个结果写进cases/p01.expected和cases/p02.expected,后面批量脚本就能自动比对。

3.3 用 Python 写批量对照脚本:一眼看出答案偏移

题目一多,手工比对容易漏。我一般会写一个很小的 Python 脚本,读cases/下的输入文件,调用编译好的可执行文件,再把实际输出和期望输出并排打印。脚本不追求通用,只要能一眼看出“哪题偏了、偏成什么”就够。

import subprocess from pathlib import Path base = Path("contest_pdf") exe = base / "out" / "run" cases = base / "cases" for inp in sorted(cases.glob("*.in")): name = inp.stem expected_file = cases / f"{name}.expected" if not expected_file.exists(): continue expected = expected_file.read_text(encoding="utf-8").strip() # 输入文件第一行是 task 编号,后面是题目输入 proc = subprocess.run( [str(exe)], input=inp.read_text(encoding="utf-8"), text=True, capture_output=True, check=False ) actual = proc.stdout.strip() flag = "OK" if actual == expected else "DIFF" print(f"{name}: {flag} expected={expected!r} actual={actual!r}") if proc.stderr: print(f" stderr: {proc.stderr.strip()}")

脚本逻辑很直:遍历*.in,找同名*.expected,用subprocess.run把输入喂给可执行文件,比较去掉首尾空白后的输出。参数说明:input=传字符串,text=True让输入输出按文本处理,capture_output=True同时接住 stdout 和 stderr,check=False避免程序非零退出时脚本直接中断。实际使用时把base改成自己的目录,exe改成编译产物路径即可。

这个脚本的价值不在自动化本身,而在“错题定位”。比如某题期望 3、实际 4,基本能判断是循环边界多算了一位;期望 36、实际 6,基本能判断是输出成了最大公约数而不是最小公倍数。把DIFF行贴进notes/错题表.md,后面复习时不用重新翻 PDF。

4. 长题干题怎么建模:手机菜单、视频压缩、骰子与爬山的四套推演表

4.1 手机菜单题:位置与编号分离的状态机

手机菜单题最绕的地方是“应用编号”和“图标位置”不是一回事。题目给的初始排列是每个应用图标在菜单中的位置,启动序列给的是应用编号。每次启动后,系统会把该应用的图标位置与前一个位置的图标交换。如果只用一个数组记录“第几个应用在哪”,更新时很容易把编号当位置。

我一般用两个数组:pos[app]存应用当前所在位置,at[position]存某个位置上当前是哪个应用。启动应用x时,先取p = pos[x],滚动次数按p算,不按x算。滚动到目标屏的公式是(p - 1) / k,其中k是每屏容量,位置从 1 开始。然后加 1 次双击操作。接着如果p > 1,交换位置p和p - 1上的应用,同时更新两个数组;如果p == 1,不交换。

步骤操作状态更新
1读入应用编号 x取 p = pos[x]
2算滚动次数(p - 1) / k
3加双击操作ans += 1
4若 p > 1,交换 p 与 p-1更新 pos 和 at
5处理下一个启动编号回到步骤 1

这套状态机的可执行训练方法是:先拿 3 个应用、每屏 2 个图标、启动 3 次的小数据手推,把每一步的pos和at都写出来。手推两轮后,再写代码。代码里不要省at数组,只维护pos会在交换时找不到“前一个位置上是哪个应用”。边界检查两个:位置为 1 不交换;最后一屏可能不满,但滚动次数公式不受影响。

4.2 视频压缩题:服务器队列与时间线模拟

视频压缩题的核心是“服务器按上传顺序取视频,谁先空闲谁接下一个”。题干里服务器数量、视频数量、上传时间、视频长度、压缩速率混在一起,最容易错的是单位。常见做法是先统一成秒,再维护每个服务器的空闲时间。视频到达时,取当前最早空闲的服务器,开始时间等于max(到达时间, 服务器空闲时间),完成时间等于开始时间加压缩耗时。

视频上传时间长度分配服务器开始时间完成时间
102 分钟S10压缩耗时
211 分钟S211 + 压缩耗时
321 分钟S322 + 压缩耗时
431 分钟最早空闲max(3, 空闲时间)开始 + 耗时

模拟时不要一上来算所有视频,先算前三个,确认“同一秒多个视频到达”和“服务器刚好空闲”两种情况。如果题干说每个服务器每秒压缩固定时长,就把长度除以速率;如果速率是“每几秒压缩一分钟”,就先换算成“压缩一分钟需要几秒”。这类题的错误选项通常是把“完成时间”写成“开始时间”,或者把“上传时间”当成“开始时间”。表格列清楚后,逐行核对即可。

4.3 骰子与爬山题:可行性剪枝与区间约束

骰子题给每个骰子的面数,问某个骰子取某个数字时,是否可能让总和等于目标值。直接枚举所有组合会爆炸,正确做法是算剩余骰子的最小和与最大和。固定第i个骰子取v后,剩余骰子的最小和是剩余数量,最大和是剩余面数之和。如果目标值减去v落在[min_rest, max_rest]内,这个取值就可能。对每个骰子、每个面都做一次这个检查,复杂度是面数之和,完全够用。

爬山题给起点、终点和相邻两天海拔差限制,问可能达到的最高海拔。做法是从左到右推一个上界:left[i] = min(left[i-1] + d, 某个已知约束);再从右到左推一个上界:right[i] = min(right[i+1] + d, ...);每个位置的可达最高值取min(left[i], right[i])。如果起点和终点固定,先把两端设成已知值,再向中间推。边界检查:相邻差限制是“不超过”,不是“必须等于”;起点和终点本身不能改。

题型核心约束推演方向易错点
骰子求和每个骰子取值 1 到面数固定一个取值,检查剩余和区间忘记剩余骰子最小值不是 0
小猴爬山相邻两天差不超过 d左推上界、右推上界,取较小值把起点终点当成可调整值

5. 避坑与排查:这份 PDF 刷题时最容易翻车的五件事

5.1 五类高频翻车现场

第一类,题干排版错位导致条件读漏。现象是做完发现“少看了一个变量”或“把范围看反了”。原因常见于 PDF 分栏、公式和选项挤在一起,读题时视线跳行。解决方法是先只读题干,不读选项,用笔把变量名、范围、单位圈出来;再读选项。手机菜单题和视频压缩题尤其要这样处理。

第二类,程序阅读题把“输入范围”当“输出范围”。现象是手推时用了一个很大的输入,推着推着乱了。原因是题目程序可能只适合小输入手推,大输入应该看循环边界和变量职责。解决方法是用最小输入先跑一轮,再用能触发分支的输入跑第二轮,不要一上来就代大数。

第三类,长题干模拟题的时间单位不统一。现象是视频压缩题算出来的完成时间和选项差一个倍数。原因是题干里秒、分钟、压缩速率混着写。解决方法是先写单位换算表,把所有时间统一成秒,再开始模拟。表格里专门留一列“统一后单位”。

第四类,单选题选项缺失时硬猜。现象是 PDF 里某些选项显示不全,凭印象选了一个。原因是扫描或排版导致符号丢失。解决方法是把题干和选项一起复制到错题表,缺失处标“待补”,先按程序逻辑推答案,再对照选项。不要用“看起来像”补选项。

第五类,用答案反推思路的副作用。现象是同一道题做对了,换个数就不会。原因是记住的是选项字母,不是程序状态变化。解决方法是每道错题写一句“如果输入改成 X,输出会变成什么”,用变式题验证自己是否真的理解。

5.2 排查清单与修复动作

症状优先检查修复动作
手推结果和程序输出不一致循环边界、初值、break/continue把循环变量每轮打印出来,对照三列法
长题干题读完不知道变量谁是谁是否区分了编号和位置、时间与时长先画变量表,再画状态表
同一知识点反复错错因标签是否太粗把“语法错”拆成“首字符错/关键字错/符号错”
批量脚本全报 DIFF输入文件第一行 task 编号、可执行文件路径先手工跑一个用例,再跑脚本
选项和题干对不上PDF 排版是否丢符号复制到文本编辑器,补齐缺失处再判断

排查时我一般按“先最小用例,再批量脚本,最后错题表”的顺序走。最小用例能确认程序本身没跑错,批量脚本能确认对照关系没建错,错题表能确认错因没有归粗。三步都过一遍,比反复看答案有效。

6. 把试题变成训练包:三个可复用技巧与一条验证习惯

这份 PDF 的价值不只在“做一遍对答案”,而在把它拆成可复用训练包。第一个技巧是按题型建三个目录:basic/放基础知识错题,read/放程序阅读复现代码,model/放长题干建模表。每个目录只放一种东西,复习时不用翻整份 PDF。第二个技巧是给每道程序阅读题配一个“变式输入”,比如把约数题的输入从 6 改成 12,把最小公倍数题的输入从 12 和 18 改成 15 和 20,用输出变化验证自己是不是真懂。第三个技巧是把长题干题的变量表做成模板,手机菜单用“编号/位置”两列,视频压缩用“到达/开始/完成”三列,骰子用“固定值/剩余最小/剩余最大”三列,下次遇到同类题直接套。

训练包目录放什么复习动作
basic基础知识错题与错因标签每周只看错因标签,不看题号
read每道程序阅读题的 cpp 与用例改一个输入,重跑一次
model长题干变量表与约束表遮住答案,只推表格

验证习惯只有一条:每道程序阅读题至少跑一次本地编译,每道长题干题至少写一张变量表,做完后把“手推结果”和“程序/表格结果”并排写。从那以后我每次带人刷这类校级预选赛 PDF,都强制走一遍“最小用例—批量对照—错题归因”三步,不跳过。希望帮到你。

本文还有配套的精品资源,点击获取

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/31 3:40:08

PolarisCTF Web赛题解析:SQL注入与XXE漏洞实战

1. PolarisCTF招新赛Web题目复现概述作为国内知名的网络安全竞赛平台&#xff0c;PolarisCTF每年都会举办面向新人的招新赛事。今年的Web安全赛题延续了往年的技术风格&#xff0c;涵盖了从基础到进阶的各类Web漏洞类型。本文将选取其中5道具有教学价值的题目进行完整复现&…

作者头像 李华
网站建设 2026/10/31 3:39:39

开源GNN评估仪表盘:提升软件测试效能的下一代工具

1. 开源GNN评估仪表盘&#xff1a;软件测试社区的下一代效能工具在软件测试领域&#xff0c;评估模型性能一直是个痛点。传统方法要么依赖静态报告&#xff0c;要么需要手动整理数据&#xff0c;效率低下且难以追踪历史变化。我们团队基于图神经网络(GNN)开发的评估仪表盘&…

作者头像 李华
网站建设 2026/10/31 3:38:57

制造业AI落地避坑指南:从伪专家到实战者的经验总结

干制造业AI落地这行十几年&#xff0c;我参加过不下百场项目对接会&#xff0c;听过无数顶着各种头衔的"AI专家"在台上讲"智能工厂""数字化转型"。讲得是真漂亮&#xff0c;但一聊到具体的产线数据、工艺节拍、设备接口&#xff0c;就开始打太极…

作者头像 李华
网站建设 2026/10/31 3:38:56

从代码补全到软件工程智能体:Codex实践复盘

说句实在话&#xff0c;代码生成大模型这个概念这几年已经被讲烂了&#xff0c;但真正拿它干活的人心里都清楚&#xff0c;光靠“补全下一段代码”根本撑不起完整的软件工程。Codex真正让人兴奋的点&#xff0c;是把大模型的能力从“你问我答”的对话工具&#xff0c;硬生生拉到…

作者头像 李华
网站建设 2026/10/31 3:38:50

AI驱动的渗透测试:LLM如何革新安全攻防

1. 当AI遇上渗透测试&#xff1a;LLM如何重构安全攻防三年前我参与某次红队演练时&#xff0c;曾花费整整三天手工编写针对特定CMS的漏洞利用代码。如今借助大语言模型&#xff08;LLM&#xff09;&#xff0c;同样的工作只需在ChatGPT对话框中输入自然语言指令&#xff0c;30秒…

作者头像 李华
网站建设 2026/10/31 3:38:07

极值点、驻点与鞍点:导数判别、不可导点及优化应用

1. 一个反例摆上台面&#xff1a;导数等于零的位置&#xff0c;凭什么可能什么都不是带过几轮答疑之后&#xff0c;我发现一个特别稳定的现象&#xff1a;凡是卡在极值点和驻点这两个概念上的&#xff0c;十有八九不是不会求导、不会解方程&#xff0c;而是边界没划清。有人算出…

作者头像 李华