news 2026/10/2 6:26:06

海淀信息学竞赛预选赛试题拆解:程序阅读、数组与循环的编程能力门槛

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
海淀信息学竞赛预选赛试题拆解:程序阅读、数组与循环的编程能力门槛

简介:这份PDF是2024年海淀区中小学生信息学竞赛校级预选赛的完整试题,面向备战信息学竞赛的中小学生及指导教师,用于检验编程基础与代码阅读能力。试题分为编程基础知识单选题和程序阅读单选题两大部分,覆盖变量命名规则、赋值语句、数据类型、二进制与十进制转换、表达式运算、逻辑判断、函数定义与调用、运算符特性以及for与while循环、break和continue等核心考点,程序阅读题则要求根据给定代码片段推断输出结果或变量取值,着重考察逻辑思维与代码分析能力。资源包内仅含1个PDF文件,大小约422KB,轻量便携,适合打印练习或电子设备随时查阅。目前已有574人学习下载,可作为赛前自测、课堂训练或知识点查漏补缺的实用材料,帮助考生熟悉竞赛题型与难度,系统巩固编程基础。

1. 海淀区信息学竞赛预选赛试题拆解:从一份 PDF 看小学高年级到初中的编程能力门槛

海淀区中小学生信息学竞赛的校级预选赛,每年都会流出一份 PDF 试题,文件名通常带日期编号,比如「2024年海淀区中小学生信息学竞赛校级预选赛试题1103.pdf」。很多家长和刚带竞赛的老师拿到这份文件的第一反应是——题目看着不难,但孩子做不对;或者孩子能写代码,但读不懂题。这份卷子的真正价值不在于题目本身有多难,而在于它精确划出了一条能力线:程序阅读能力、数组操作熟练度、循环语句的嵌套运用,这三项是预选赛筛选的核心维度。它适合谁?适合正在带小学高年级到初一学生备战信息学竞赛的教练,也适合想判断自己孩子是否「够格」进入竞赛体系的家长。下面我从这份试题的典型结构出发,把每个技术点的训练路径和落地方法讲清楚。

2. 程序阅读题为什么是预选赛第一道分水岭

2.1 程序阅读考的不是「看懂」,是「模拟执行」

预选赛的程序阅读题通常给出一段 15 到 30 行的代码,涉及循环嵌套、数组读写、条件分支的组合,然后问「最终输出是什么」或「循环体执行了几次」。很多学生习惯用「大概理解逻辑」的方式去读,结果在循环边界上翻车。这类题的正确做法是手动模拟执行:拿一张草稿纸,画出变量表,逐行跟踪每个变量的值。

我一般让学生按这个格式做模拟:

行号 | i | j | sum | arr[0] | arr[1] | arr[2] | 输出 -----|---|---|-----|--------|--------|--------|----- 3 | 0 | - | 0 | - | - | - | 4 | 0 | 0 | 0 | - | - | - | 5 | 0 | 0 | 0 | 1 | - | - |

这个表格看起来笨,但它是程序阅读题唯一可靠的解法。海淀的预选赛题目有个特点:循环变量的起始值和终止条件经常不是 0 和 n-1,而是 1 和 n,或者用了i <= n而不是i < n。这种「差一错误」是出题人故意设置的筛选点。

2.2 用 Python 还原试题中的循环结构

拿到试题后,不要只看,要把题目中的伪代码或 C++ 代码用 Python 重写一遍,跑出结果来验证自己的模拟是否正确。以下是一道典型的预选赛程序阅读题的还原:

# 还原海淀预选赛常见的循环嵌套 + 数组累加题型 arr = [3, 1, 4, 1, 5, 9, 2, 6] n = len(arr) total = 0 for i in range(n): for j in range(i + 1, n): if arr[i] < arr[j]: total += arr[j] - arr[i] print(total)

这段代码的逻辑是:对数组中每一对满足arr[i] < arr[j]的元素,累加它们的差值。参数说明:外层循环i从 0 到 n-1,内层循环j从i+1到 n-1,保证每对元素只比较一次。total初始为 0,每次累加正差值。运行结果是 24。如果学生模拟时把内层循环写成range(i, n),就会多算arr[i] - arr[i] = 0的情况,虽然结果不变,但循环次数会多出 n 次,在「循环体执行几次」这类问题上就会答错。

提示:程序阅读题中,循环次数的计算比输出结果更容易出错。建议先算循环次数,再算输出值,两个答案互相验证。

2.3 分支与循环语句的组合陷阱

预选赛题目中,break和continue的出现频率很高。常见套路是:在双层循环中,内层遇到某个条件就break,然后外层继续执行。学生容易误以为break会跳出所有循环。以下是一道典型题的还原:

# 还原 break 在嵌套循环中的行为 count = 0 for i in range(1, 6): for j in range(1, 6): if i * j > 10: break count += 1 # 注意:break 只跳出内层循环 print(count)

逻辑说明:外层i从 1 到 5,内层j从 1 到 5。当i*j > 10时,内层break,但外层继续。count统计的是所有满足i*j <= 10的组合数。手动计算:i=1 时 j 从 1 到 5 全部满足,count=5;i=2 时 j 从 1 到 5 全部满足(25=10 不触发 break),count=10;i=3 时 j=1,2,3 满足(34=12 触发 break),count=13;i=4 时 j=1,2 满足(43=12 触发 break),count=15;i=5 时 j=1,2 满足(53=15 触发 break),count=17。最终输出 17。

参数说明:range(1, 6)生成 1 到 5 的整数。break只作用于当前所在的那一层循环。如果题目问的是「内层循环体总共执行了几次」,那就要把每次进入内层循环的次数都算上,包括触发break的那一次。

注意:海淀预选赛的程序阅读题经常把break和continue放在一起考,continue跳过本次循环剩余语句,break直接终止当前层循环。两者的区别在模拟执行时一定要逐行标注。

3. 数组操作:从一维到二维的必考题型与代码模板

3.1 数组初始化与遍历的三种写法

预选赛的编程题中,数组是最核心的数据结构。常见题型包括:读入 n 个数存入数组、求最大值/最小值、统计满足条件的元素个数、数组去重、数组排序。这些题目的基础是数组的初始化和遍历。以下三种写法必须让学生练到肌肉记忆:

# 写法一:直接初始化 arr1 = [0] * 10 # 生成 [0,0,0,0,0,0,0,0,0,0] # 写法二:列表推导式初始化 arr2 = [i * 2 for i in range(10)] # [0,2,4,6,8,10,12,14,16,18] # 写法三:从输入读取 n = int(input()) arr3 = list(map(int, input().split())) # 读入一行空格分隔的整数

逻辑说明:写法一适合需要预分配空间的场景,比如计数数组。写法二适合生成有规律的序列。写法三适合竞赛输入格式。参数说明:[0] * 10生成 10 个 0 的列表;range(10)生成 0 到 9;map(int, input().split())把一行输入按空格切分后转为整数。

在海淀预选赛中,数组下标从 0 开始还是从 1 开始,题目通常会明确说明。如果没有说明,默认从 0 开始。但有些题目会给出「第 1 个数」这样的描述,此时建议用arr = [0] + list(map(int, input().split()))的方式,让下标从 1 开始,避免转换时出错。

3.2 二维数组的读入与行列遍历

二维数组是预选赛区分度最高的题型之一。常见题目包括:矩阵转置、矩阵求和、找鞍点、螺旋输出。以下是一道典型的二维数组读入和遍历的代码:

# 读入 n 行 m 列的二维数组 n, m = map(int, input().split()) matrix = [] for i in range(n): row = list(map(int, input().split())) matrix.append(row) # 按行遍历求和 row_sum = [] for i in range(n): s = 0 for j in range(m): s += matrix[i][j] row_sum.append(s) # 按列遍历求和 col_sum = [] for j in range(m): s = 0 for i in range(n): s += matrix[i][j] col_sum.append(s) print("行和:", row_sum) print("列和:", col_sum)

逻辑说明:matrix是一个列表的列表,matrix[i][j]表示第 i 行第 j 列的元素。按行遍历时外层循环是行号,内层是列号;按列遍历时外层是列号,内层是行号。参数说明:n和m分别表示行数和列数,row_sum存储每行元素之和,col_sum存储每列元素之和。

提示:二维数组题目中,行列下标写反是最常见的翻车原因。建议在草稿纸上画出矩阵,标出行号和列号,再写代码。

3.3 数组去重与排序的竞赛写法

预选赛中数组去重和排序通常不要求手写复杂算法,但要求学生掌握基本方法。Python 中可以用集合去重后转回列表,再排序:

# 数组去重并排序 arr = [3, 1, 4, 1, 5, 9, 2, 6, 5, 3] unique_sorted = sorted(set(arr)) print(unique_sorted) # [1, 2, 3, 4, 5, 6, 9] # 如果要求保持原顺序去重 seen = set() result = [] for x in arr: if x not in seen: seen.add(x) result.append(x) print(result) # [3, 1, 4, 5, 9, 2, 6]

逻辑说明:set(arr)自动去重,sorted()返回排序后的列表。保持原顺序去重需要借助seen集合记录已出现的元素。参数说明:seen是一个辅助集合,result存储去重后的结果。

在海淀预选赛中,如果题目要求「输出去重后的数组,按原顺序」,就必须用第二种写法。如果只要求「输出去重后的元素」,两种写法都可以。注意set是无序的,直接list(set(arr))的顺序是不确定的,不能用于要求保持顺序的题目。

4. 循环语句的嵌套与边界:预选赛编程题的得分关键

4.1 循环嵌套的三种典型结构

预选赛编程题中,循环嵌套主要有三种结构:直角三角形的星号输出、乘法口诀表、以及数组的双重遍历。这三种结构的代码模板必须熟练到不用思考就能写出来:

# 结构一:直角三角形 n = 5 for i in range(1, n + 1): print("*" * i) # 结构二:乘法口诀表 for i in range(1, 10): for j in range(1, i + 1): print(f"{j}*{i}={i*j}", end="\t") print() # 结构三:数组双重遍历找满足条件的元素对 arr = [2, 7, 11, 15] target = 9 for i in range(len(arr)): for j in range(i + 1, len(arr)): if arr[i] + arr[j] == target: print(f"找到: {arr[i]} + {arr[j]} = {target}")

逻辑说明:结构一外层控制行数,内层用字符串乘法控制每行星号数量。结构二外层控制行,内层控制每行的列数,end="\t"让输出不换行。结构三外层和内层配合遍历所有不重复的元素对。参数说明:range(1, n+1)生成 1 到 n;range(i+1, len(arr))保证每对元素只比较一次。

4.2 循环边界:从 0 开始还是从 1 开始

这是预选赛中最容易丢分的地方。以下是一道典型题的两种写法对比:

# 题目:计算 1 到 100 中所有能被 3 或 5 整除的数的和 # 写法一:从 1 开始 total1 = 0 for i in range(1, 101): if i % 3 == 0 or i % 5 == 0: total1 += i print(total1) # 2418 # 写法二:从 0 开始(错误示范) total2 = 0 for i in range(0, 100): if i % 3 == 0 or i % 5 == 0: total2 += i print(total2) # 2318,少了 100

逻辑说明:range(1, 101)生成 1 到 100,range(0, 100)生成 0 到 99。0 能被 3 整除但不影响求和,但 100 被漏掉了。参数说明:range(a, b)生成从 a 到 b-1 的整数。要包含 b,必须写range(a, b+1)。

注意:预选赛题目中,「1 到 n」和「0 到 n-1」是两种完全不同的范围。读题时把范围用笔圈出来,写代码前先确认range的起止参数。

4.3 用循环解决数组统计类问题

预选赛的编程题中,循环和数组经常结合出现。以下是一道典型的统计题:

# 题目:读入 n 个学生的成绩,统计各分数段人数 n = int(input()) scores = list(map(int, input().split())) # 分数段:0-59, 60-69, 70-79, 80-89, 90-100 buckets = [0] * 5 for s in scores: if s < 60: buckets[0] += 1 elif s < 70: buckets[1] += 1 elif s < 80: buckets[2] += 1 elif s < 90: buckets[3] += 1 else: buckets[4] += 1 for i, count in enumerate(buckets): print(f"分数段{i}: {count}人")

逻辑说明:buckets是一个长度为 5 的计数数组,每个元素对应一个分数段。遍历scores时,根据分数落入的区间,对相应的buckets元素加 1。参数说明:buckets[0]对应 0-59,buckets[4]对应 90-100。enumerate(buckets)同时获取下标和值。

这道题的易错点在于边界条件:60 分应该归入第二个分数段,而不是第一个。代码中用s < 60而不是s <= 59,效果一样,但s < 60更直观。如果题目要求「60 分以上(含 60)为及格」,那 60 分就要归入及格段。

5. 避坑与排查:预选赛带训中最容易翻车的五个点

5.1 输入格式没对齐,程序直接报错

现象:学生写的代码在本地测试通过,但提交后报「运行错误」或「答案错误」。原因:预选赛的输入格式通常是一行多个整数,用空格分隔,但有些题目是每行一个整数,或者第一行是 n,第二行是 n 个整数。学生用input()读一行,但实际数据有多行。解决:读题时先确认输入格式。如果是多行输入,用sys.stdin.read().split()一次性读完,再按需切分:

import sys data = sys.stdin.read().split() n = int(data[0]) arr = list(map(int, data[1:1+n]))

5.2 数组下标越界,循环多跑了一次

现象:程序在本地运行正常,但提交后部分测试点报错。原因:循环范围写成了range(n+1)或range(1, n+1)但数组长度只有 n,访问arr[n]时越界。解决:在循环内访问数组前,先确认下标最大值。如果数组长度为 n,下标范围是 0 到 n-1。用range(n)而不是range(n+1)。

5.3 变量未初始化,累加结果随机

现象:多次运行同一份代码,结果不一样。原因:累加变量sum或count没有初始化为 0,或者初始化放在了循环内部。解决:所有累加变量在循环开始前初始化为 0。以下是对比:

# 错误:total 在循环内初始化 for i in range(5): total = 0 total += i print(total) # 输出 4,不是 10 # 正确:total 在循环外初始化 total = 0 for i in range(5): total += i print(total) # 输出 10

5.4 字符串和数字混用,比较结果不符合预期

现象:输入的数字被当作字符串比较,"10" < "9"返回True。原因:input()返回的是字符串,没有用int()转换。解决:读入后立即转换类型。如果一行有多个数字,用map(int, input().split())。

5.5 循环嵌套中 break 只跳出一层

现象:学生以为break会跳出所有循环,但实际只跳出了内层。原因:break的作用域是当前所在的那一层循环。解决:如果需要跳出多层循环,可以用标志变量或函数封装:

# 用标志变量跳出双层循环 found = False for i in range(5): for j in range(5): if i * j > 10: found = True break if found: break

6. 从预选赛到复赛:用真题训练程序阅读速度的一个具体方法

预选赛的题量通常不大,但时间紧。很多学生不是不会做,而是做不完。程序阅读题如果每道都手动模拟,时间肯定不够。我一般让学生用「三遍法」训练:

第一遍,限时 20 分钟做 5 道程序阅读题,不管对错,只求做完。第二遍,不限时,每道题用草稿纸完整模拟执行,记录每一步的变量值,和答案对照。第三遍,把做错的题目标记出来,隔一天再做一次,只看题目不写模拟,直接说出输出结果。

这个方法的关键在于第二遍。很多学生第一遍做完就扔了,没有经历「逐行模拟」的过程,下次遇到类似的循环嵌套还是会错。第二遍虽然慢,但它是把「读代码」变成「执行代码」的唯一途径。

以下是一份我常用的训练记录表:

日期题号题型第一遍用时第一遍正确第二遍模拟正确第三遍复做正确
11.031循环嵌套3min否是是
11.032数组遍历4min是是是
11.033break/continue5min否否是

这张表的作用是暴露「假会」的题目。第一遍做对但第二遍模拟发现逻辑不对的,说明是蒙对的。第一遍做错第二遍模拟也错的,说明这个知识点根本没掌握,需要重新学。

提示:程序阅读题的训练目标不是「做对」,而是「在 3 分钟内做对」。预选赛的时间压力下,速度比正确率更重要。先练速度,再练正确率。

最后说一个我自己的习惯:每次拿到新的预选赛试题,我会先自己完整做一遍,记录每道题的用时和错误点,然后再去带学生。这样做的原因是,只有自己踩过坑,才知道学生在哪个步骤会卡住。海淀的题每年都有微调,但核心考点——程序阅读、数组、循环——从来没变过。把这三项练到不用想就能写,预选赛的通过就是水到渠成的事。希望帮到你。

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

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

新加坡理工学院是大专吗?和国内大专的差别在哪

结论&#xff1a;不能简单等同。新加坡的理工学院&#xff08;Polytechnic&#xff0c;简称 Poly&#xff09;是三年制的高等教育机构&#xff0c;偏应用与实践&#xff0c;但它在升学通道和本地认可度上&#xff0c;和国内的“大专”并不完全对应。 Poly 到底是什么 Poly 是新…

作者头像 李华
网站建设 2026/10/2 6:24:55

脑机接口入门:从脑电采集到无线可视化的完整链路实战

脑机接口、EEG 可视化、注意力监测&#xff0c;这几年被开源项目和短视频带火了不少&#xff0c;但大部分教程都停在“模块能出波形”这一步。真正拿一块脑电模块&#xff0c;想做成从传感器到屏幕、再到网页的完整无线链路时&#xff0c;很多人会卡在三个地方&#xff1a;数据…

作者头像 李华
网站建设 2026/10/2 6:24:54

硬件消抖电路设计:RC滤波与施密特触发器实战指南

1. 按键为什么“一按变三按”&#xff1a;从机械结构讲清弹跳本质你有没有试过在单片机开发板上接一个轻触开关&#xff0c;写个最简单的上升沿触发计数程序&#xff0c;结果按下一次&#xff0c;LED却闪了三四下&#xff1f;或者用示波器抓取按键引脚波形&#xff0c;发现按下…

作者头像 李华
网站建设 2026/10/2 6:23:28

开源项目Tiger AI Platform平台中使用的模型详解:模型032-china rocket Traningmodel 完全指南:原理、TigerPro 接入、代码实战与落地案例

目录 china rocket Traningmodel 完全指南:原理、TigerPro 接入、代码实战与落地案例(`china_rocket_Traningmodel`) 1. 开篇:这个模型解决什么问题 1.1 目标检测在业务里真正交付什么 1.2 输出如何被下游消费 1.3 复杂度与评测口径(加分项) 1.4 适合用 / 不适合用 2. 模…

作者头像 李华