资讯动态

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

发布时间:2026/10/2 6:26:06 来源:尧图企业网站定制
简介这份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从i1到 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的组合数。手动计算i1 时 j 从 1 到 5 全部满足count5i2 时 j 从 1 到 5 全部满足2510 不触发 breakcount10i3 时 j1,2,3 满足3412 触发 breakcount13i4 时 j1,2 满足4312 触发 breakcount15i5 时 j1,2 满足5315 触发 breakcount17。最终输出 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 到 9map(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, n1)生成 1 到 nrange(i1, 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 到 100range(0, 100)生成 0 到 99。0 能被 3 整除但不影响求和但 100 被漏掉了。参数说明range(a, b)生成从 a 到 b-1 的整数。要包含 b必须写range(a, b1)。注意预选赛题目中「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-59buckets[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:1n]))5.2 数组下标越界循环多跑了一次现象程序在本地运行正常但提交后部分测试点报错。原因循环范围写成了range(n1)或range(1, n1)但数组长度只有 n访问arr[n]时越界。解决在循环内访问数组前先确认下标最大值。如果数组长度为 n下标范围是 0 到 n-1。用range(n)而不是range(n1)。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) # 输出 105.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: break6. 从预选赛到复赛用真题训练程序阅读速度的一个具体方法预选赛的题量通常不大但时间紧。很多学生不是不会做而是做不完。程序阅读题如果每道都手动模拟时间肯定不够。我一般让学生用「三遍法」训练第一遍限时 20 分钟做 5 道程序阅读题不管对错只求做完。第二遍不限时每道题用草稿纸完整模拟执行记录每一步的变量值和答案对照。第三遍把做错的题目标记出来隔一天再做一次只看题目不写模拟直接说出输出结果。这个方法的关键在于第二遍。很多学生第一遍做完就扔了没有经历「逐行模拟」的过程下次遇到类似的循环嵌套还是会错。第二遍虽然慢但它是把「读代码」变成「执行代码」的唯一途径。以下是一份我常用的训练记录表日期题号题型第一遍用时第一遍正确第二遍模拟正确第三遍复做正确11.031循环嵌套3min否是是11.032数组遍历4min是是是11.033break/continue5min否否是这张表的作用是暴露「假会」的题目。第一遍做对但第二遍模拟发现逻辑不对的说明是蒙对的。第一遍做错第二遍模拟也错的说明这个知识点根本没掌握需要重新学。提示程序阅读题的训练目标不是「做对」而是「在 3 分钟内做对」。预选赛的时间压力下速度比正确率更重要。先练速度再练正确率。最后说一个我自己的习惯每次拿到新的预选赛试题我会先自己完整做一遍记录每道题的用时和错误点然后再去带学生。这样做的原因是只有自己踩过坑才知道学生在哪个步骤会卡住。海淀的题每年都有微调但核心考点——程序阅读、数组、循环——从来没变过。把这三项练到不用想就能写预选赛的通过就是水到渠成的事。希望帮到你。本文还有配套的精品资源点击获取

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑