全国青少年信息素养大赛(原全国青少年电子信息智能创新大赛)是“世界机器人大会青少年机器人设计与信息素养大赛”赛事之一,由中国电子学会主办,包含很多赛项,大赛自2013年举办,已连续成功举办八届,已正式入围“2022-2025学年面向中小学生的全国性竞赛活动名单”。
大赛旨在激发广大青少年的科学兴趣和想象力,培养钻研探究、创新创造的科学精神和实践能力,促进青少年科技创新活动的广泛开展,发现和培养一批具有科研潜质和创新精神的青少年科技创新后备人才。
大赛主要竞赛类别包括电子科技、智能机器人、软件编程三类,全国青少年Python编程挑战赛就属于其中的软件编程类。
一.赛事说明
2021-2022年(第8届)Python挑战赛赛程分为初赛、复赛和总决赛三个阶段。初赛是资格赛,复赛是地方选拔赛,总决赛是全国各地选拔的精英汇聚在一起进行PK。2021-2022年全国青少年Python编程挑战全国总决赛于2022年8月27日正式举行。一共是10道编程题,每道题100分,满分1000分,考试时间是120分钟。
10道编程题分别如下:
- 分苹果
- 韩信点兵
- 借书问题
- 四位数密码
- 邮票面值
- 组合取球
- 统计连续字符
- n的n次方
- 海盗搜身
- 父与子
超平老师将分10讲对每道题进行详细的解读和剖析,今天要解读的是第9题,海盗搜身。
二.题目描述
题目背景:
—群渔民被海盗抓住了,依次坐在编号为1~n的凳子上,其中有一个人身上有藏宝图。
现在海盗想要找那个身上带着宝藏的渔民,海盗先将1号凳子上面的人搜身,没找到就隔1个凳子,将3号凳子上面的人搜身,没找到就隔2个凳子,将6号凳子上面的人搜身。
以后每次多隔一个凳子去搜索……这样下去找了100次没找到,最终放弃了把渔民释放了。
任意输入一个数字n(5 <= n <= 20)代表渔民的数量,依次输出哪些编号的渔民不会被搜身。
输入描述:
任意输入一个数字n(5 <= n <= 20)代表渔民的数量
输出描述:
依次输出哪些编号的渔民不会被搜身,每行一个
样例输入:
10
样例输出:
2
4
7
9
注意:
input()内不添加任何参数
只有完全正确才可提交,若无法点击提交说明答题存在错误,可及时进行检查并修改
三.思路分析
读完题目之后,你可能会有这样的疑问,渔民是怎么排列的呢?题目并没有描述清楚。
不过要确保能搜索100次,只有两种情况,一是队伍特别长,二是循环排列。实际上,渔民的数量最多只有20次,因此只能是第二种情况,也就是说,渔民是围成一圈依次坐在编号为1~n的凳子上的。
这有点类似于著名的“约瑟夫环问题”,在约瑟夫环问题中,每次会减少一个人,并且间隔是固定不变的。
本题所描述的场景中,人是固定不变的,但是每次间隔的数字是变化的,从1开始,然后是2、3、4…。
我们可以使用一个列表用来保存所有渔民的编号,从1开始,到n结束,然后模拟搜身的过程。
从第一个人开始遍历,如果搜到对应的渔民,将列表项修改为-1,然后按照间隔搜索下一个人,不停的重复过程。
当搜索到第n个人的时候,下一个人就回到第一个人了,这需要使用余数运算。
接下来,我们进入具体的编程实现环节。
四.编程实现
根据上面的思路分析,我们编写代码如下:
简单说明3点:
1). 变量j用来表示下标,列表中的值是从1开始编号的,但是遍历列表时,需要从下标0开始,因此j的初始值为0;
2). 变量step表示间隔,从第一个人开始搜身,下一次要间隔两个人,所以初始值为2,每循环一次,step就增加1;
3). j每次增加step,一旦超出n的值,就需要回到0,这是通过余数运算来实现的,即j = (j + step) % n,这是我们在处理环问题时的通用方法。
以10为例,首先进行编号,编号分别为1、2、3、4、5、6、7、8、9、10,如下:
经过100次搜索之后,其结果为:
值为-1的就表示已经搜过身了,然后进行过滤,将大于0的列表项留下,就是不会被搜身的渔民了,如图:
五.总结与思考
本题难度较大,考查的知识点主要包括:
- 输入输出函数;
- 列表操作,尤其是列表推导式的灵活运用;
- for…in循环,注意两种for循环的区别;
- 余数的灵活运用;
对于小学和初中的孩子来说,本题的难度不小,首当其冲的就是要读懂题目的意思,虽然题目描述的没有那么清晰,但是通过自己的分析还是可以理解其真实意图的。
既然提到约瑟夫环问题,超平老师就给你留一个小作业,请你编程求解约瑟夫环问题。
设编号为1,2,……n的n个人围坐一圈,约定编号为k(k大于等于1并且小于等于n)的人从1开始报数,数到m的那个人出列。它的下一位继续从1开始报数,数到m的人出列,依次类推,直到所有人都出列为止。