[导读]:超平老师的Scratch蓝桥杯真题解读系列在推出之后,受到了广大老师和家长的好评,非常感谢各位的认可和厚爱。作为回馈,超平老师计划推出《Python蓝桥杯真题解析100讲》,这是解读系列的第1讲。
数字组合,本题是2019年3月24日举行的第10届蓝桥杯青少组Python编程第1题,题目要求将1、3、5、8这4个数字进行组合得到无重复的三位数。
先来看看题目的要求吧。
编程实现:
用 1、3、5、8 这几个数字,能组成的互不相同且无重复数字的三位数各是多少?总共有多少个?
输入描述:
无
输出描述:
多行数字,每行一个三位数组成的三位数的总个数
将程序命名为“lq001”。
评判标准:
10 分:能输出至少一个三位数字;
30 分:输出了多于10个三位数字,且确实不重复;
50 分:完全符合题意,即在30分标准的基础上,正确地输出了可组合的三位数和组合后三位数的总数量。
这是一道典型的排列组合题目,考查的知识点包括循环和列表运算。
对于本题通常有如下两种解决方案:
枚举算法
组合函数
所谓的枚举算法,就是使用循环语句将所有的情况都列举出来,这也是计算机最擅长的事情。
要组合成一个三位数,可以分成如下3步:
1). 从4个数字中选定一个数字,作为百位;
2). 从剩下的3个数字中选定一个数字,作为十位;
3). 从剩下的2个数字中选一个数字,作为个位;
我们可以借助树形图来理解组合的过程,这里只列出了百位为1的情况,如图所示:
当百位为1时,一共有6种不同的组合,相应的,百位还可以分别设置为3、5、8,以此类推,一共有24种不同的组合。
因此,我们可以使用三层循环,分别实现百位、十位和个位的选择。
这里的难点在于,在选定一个数字之后,如何去掉这个数字,以避免重复呢,你有什么好的思路吗?
一般来说,可以有如下两种方式:
1). 每一次都从4个数字中选定一个数字,然后再过滤掉重复的数字;
2). 每选定一个数字,就从列表中去掉这个数字,但需要额外使用一个列表,否则一轮循环完毕,列表就为空了。
至于组合函数的方法,就比较简单了,直接使用itertools库中提供的permutations函数就可以了。
思路有了,接下来,我们就进入具体的编程实现环节。
根据上面的思路分析,我们分别使用两种方式来编写代码:
枚举算法
组合函数
1. 枚举算法
根据上面的思路分析,可以编写代码如下:
简单说明3点:
1). 3层循环,分别表示选择百位、十位和各位;
2). 为了避免重复,需要对3个数字进行判断,将重复出现的数字过滤掉;
3). 输出组合数字的时候,使用了数学的方法,当然,你也可以使用print直接输出,不过需要注意使用sep参数去掉默认的空格,参考代码如下:
print(nums[i], nums[j],nums[k], sep="")
2. 组合函数
使用组合函数,相对就简单多了,代码如下:
简单说明4点:
1). permutations是itertools库中的函数,需要先导入才能使用;
2). permutations函数有两个参数,第1个参数是可迭代对象,包括列表、字符串、元组、字典,第2个参数是组合元素的个数,比如本案例中的3;
3). permutations函数返回结果是可迭代对象,通常使用for...in循环来处理,迭代处理是其类型为元组类型;
4). 对于元组和列表,可以使用解包运算,逐个取出其中的内容。
什么是解包运算呢?
解包,也叫拆包,你可以这样理解,一个列表或字符串是一个整体,想把列表或字符串中每个元素或字符当成一个独立个体剥离出来,这个过程就是解包。
举一个简单的例子,如下:
这是一个非常好用的特性,可以极大地节省代码,赶紧收下吧。
运行程序,执行结果如下:135
138
153
158
183
185
315
318
351
358
381
385
513
518
531
538
581
583
813
815
831
835
851
853
24
至此,整个程序就全部完成了。
本题是中级组编程部分第1题,分数为80分,代码在10行以内,涉及到的知识点包括:
循环语句,尤其是嵌套循环;
条件语句及逻辑与运算;
列表操作;
枚举算法;
组合函数的基本使用;
题目难度一般,但是需要考生具备扎实的基础,尤其是列表操作,必须要熟练掌握。同时要善于使用一些常见的Python库,可以极大的提升编程的效率,这也是Python的优点之一,有大量成熟的库函数供我们使用。
超平老师给你留一个思考题,在上面的思路分析中,提到了另一种枚举的思路,每选定一个数字,就将该数字从列表中删除,你知道要如何实现吗,赶紧尝试一下吧。
你有什么好的思路和方法,也非常欢迎和超平老师分享探讨。
如果你觉得文章对你有帮助,别忘了点赞和转发,予人玫瑰,手有余香
需要源码的,可以移步至“超平的编程课”gzh。