全国青少年信息素养大赛(原全国青少年电子信息智能创新大赛)是“世界机器人大会青少年机器人设计与信息素养大赛”赛事之一,由中国电子学会主办,包含很多赛项,大赛自2013年举办,已连续成功举办八届,已正式入围“2022-2025学年面向中小学生的全国性竞赛活动名单”。
大赛旨在激发广大青少年的科学兴趣和想象力,培养钻研探究、创新创造的科学精神和实践能力,促进青少年科技创新活动的广泛开展,发现和培养一批具有科研潜质和创新精神的青少年科技创新后备人才。
大赛主要竞赛类别包括电子科技、智能机器人、软件编程三类,全国青少年Python编程挑战赛就属于其中的软件编程类。
一.赛事说明
2021-2022年(第8届)Python挑战赛赛程分为初赛、复赛和总决赛三个阶段。初赛是资格赛,复赛是地方选拔赛,总决赛是全国各地选拔的精英汇聚在一起进行PK。2021-2022年全国青少年Python编程挑战全国总决赛于2022年8月27日正式举行。一共是10道编程题,每道题100分,满分1000分,考试时间是120分钟。
10道编程题分别如下:
- 分苹果
- 韩信点兵
- 借书问题
- 四位数密码
- 邮票面值
- 取球
- 统计连续字符
- n的n次方
- 海盗搜身
- 父与子
超平老师将分10讲对每道题进行详细的解读和剖析,今天要解读的是第4题,四位数密码。
二.题目描述
题目背景:
情报员使用4位数字来传递信息,同时为了防止信息泄露,需要将数字进行加密。数据加密的规则是:
1). 每个数字都进行如下处理:该数字加上5之后除以10的余数,替换原数字;
2). 将处理后第一位数字与第三位数字进行交换,第二位数字与第四位数字进行交换;
3). 现在任意输入一个四位数n(1000 <= n <= 9999),输出加密之后的数字。
输入描述:
一个四位数
输出描述:
加密后的四位数
样例输入:
1234
样例输出:
8967
注意:
input()内不添加任何参数
只有完全正确才可提交,若无法点击提交说明答题存在错误,可及时进行检查并修改
三.思路分析
出于信息保密的目的,在信息传输或存储中,采用密码技术对需要保密的信息进行处理,使得处理后的信息不能被非受权者(含非法者)读懂或解读,这一过程称为加密。
在加密处理过程中,需要保密的信息称为“明文”,经加密处理后的信息称为“密文”。加密即是将“明文”变为“密文”的过程,反之,将“密文”变为“明文”的过程被称为解密。
本题所描述的就是对4位数进行加密的一种算法,针对此题,通常有两种思路,一是使用数学方法,二是使用列表方法。
所谓数学方法,就是将4位数的个位、十位、百位和千位分别提取出来,然后将每一位加上5之后除以10得到其余数,接下来交换数字,最后再将4个数字组合起来得到一个新的4位数,作为加密的数字。
使用数学方法的关键点在于如何提取4个数字,这需要结合整除和取余数运算,假设4位数为n,可以用如下代码获取个位、十位、百位和千位:
# 获取个位
gw = n % 10
# 获取十位
sw = n // 10 % 10
# 获取百位
bw = n // 100 % 10
# 获取千位
qw = n // 1000
同时,还需要注意一个细节,就是经过加密处理后,重新组合的时候,不能直接使用数学方法,即不能使用 qw * 1000 + bw * 100 + sw * 10 + gw的方式相加,你知道是为什么吗?
原因非常简单,如果千位为0,结果就不是4位数了,比较简单的处理方法是直接输出。
所谓列表方法,就要简单多了,直接将输入的4位数字存入列表,然后对列表中的每一项进行加密处理,处理完毕,再转成字符串,最后将字符串进行拼接即可。
不管是哪一种方法,都涉及到数字的交换,在Python编程中,有一个非常简单的交换两个变量的写法,如下:
a, b = b, a
这是一个非常实用的编程小技巧,可以为我们节省不少代码呢。
接下来,我们进入具体的编程实现环节。
四.编程实现
根据上面的思路分析,我们可以使用两种方法来实现:
- 数学方法
- 列表方法
1.数学方法
使用数学方法,代码如下:
# 方法1,数学方法
n = int(input())
# 分别获取个位、十位、百位和千位
gw = n % 10
sw = n // 10 % 10
bw = n // 100 % 10
qw = n // 1000
# 加密处理
gw = (gw + 5) % 10
sw = (sw + 5) % 10
bw = (bw + 5) % 10
qw = (qw + 5) % 10
# 数字交换
gw, bw = bw, gw
sw, qw = qw, sw
# 直接输出
print(qw,bw,sw,gw,sep="")
2.列表方法
使用列表方法,代码如下:
# 方法2,列表方法
s = input()
nums = [ str((int(x) + 5) % 10) for x in s]
nums[0],nums[2] = nums[2], nums[0]
nums[1],nums[3] = nums[3], nums[1]
print("".join(nums))
简单说明两点:
1). 第3行代码,使用了列表推导式,先将数字字符串转成整数,加密处理之后,再转成字符串,之所以要转成字符串是为了第6行代码中的连接操作;
2). 列表项和变量一样,也可以直接使用简洁的写法进行交换。
五.总结与思考
本题难度一般,考查的知识点主要包括:
- 输入输出函数;
- 运算符,重点是余数运算;
- 类型转换;
- 变量交换;
本文给出了两种不同的实现思路,简单对比一下,就可以发现,使用第二种方式代码更为简洁,但是这要求考生要熟练掌握列表的编程技巧。你还有什么更好的解题思路吗,欢迎和超平老师交流。