[导读]:超平老师的Scratch蓝桥杯真题解读系列在推出之后,受到了广大老师和家长的好评,非常感谢各位的认可和厚爱。作为回馈,超平老师计划推出《Python蓝桥杯真题解析100讲》,这是解读系列的第43讲。
回文数个数,本题是2020年9月20日举办的第12届蓝桥杯青少组Python编程选拔赛真题。题目要求编程统计不同位数的回文数的个数。
先来看看题目的要求吧。
一.题目说明
编程实现:
求不同位数的回文数的个数。
用户输入一个正整数M(2 < M < 7),M作为回文数的位数,要求输出M位的回文数共有几个及这些回文数中有几个包含数字99。
输入描述:
输入一个正整数M
输出描述:
第一行输出回文数的个数
第二行输出M位的回文数中包含数字99的有几个
样例输入:
3
样例输出:
90
1
评判标准:
-
7分:能正确输出一组数据;
-
7分:能正确输出两组数据;
-
8分:能正确输出三组数据;
-
8分:能正确输出四组数据。
二.思路分析
这是一道简单的数论问题,研究的是回文数,考察的知识点包括循环语句、条件语句和字符串运算等
关于回文数问题,在第11届的选拔赛中出现过,可以参考《输出回文数-第11届蓝桥杯选拔赛Python真题精选》。
之前我们介绍了两种方法,第一种是字符串反转法,第二种逐位比较法,即根据回文数的对称特效进行逐位比较。
今天超平老师再介绍一种数学方法,就是将数字进行反转,然后再判断反转后的逆序数字和原数字是否相等。
比如,对于数字1221,反转后的数字为1221,二者相等,所以是回文数。再比如,对于数字1223,反转后的数字为3221,二者不相等,所以不是回文数。
如何将数字反转呢,这就涉及到拆位算法,对于任何一个整数,如果要获取最低位,只需要对10取余数即可, 然后再使用整除,去掉最低位。
举个例子,给定整数n = 168,第一次拆位过程如下:
第1步:取出个位,168 % 10 = 8
第2步:去掉个位,168 // 10 = 16
经过第一次拆位,数字n变成了16,第二次拆位过程如下:
第1步:取出个位,16 % 10 = 6
第2步:去掉个位,16 // 10 = 1
经过第二次拆位,数字n变成了1,第三次拆位过程如下:
第1步:取出个位,1 % 10 = 1
第2步:去掉各位,1 // 10 = 0
此时,数字n变成了0,拆位结束。从这个过程中可以发现,如果需要最低位,就是n %10,如果需要去掉最低位的数字,就是n // 10。
一边拆位,另一边则需要重建,重建的过程就是不断地乘以10,再加上刚拆的这一位。假设m为反转后的数字,将m的初始值设为0,其重建过程如下:
第一次,我们拆出了8,重建如下:
m = m * 10 + 8 = 0 * 10 + 8 = 8
第二次,我们拆出了6,重建如下:
m = m * 10 + 6 = 8 * 10 + 6 = 86
第三次,我们拆出了1,重建如下:
m = m * 10 + 1 = 86 * 10 + 1 = 861
这样,我们就可以得到168的逆序数字861了。
为了方便,我们可以将判断回文数的过程定义为一个函数,给定一个数字,如果是回文数就返回True,否则返回False。
除了统计所有回文数的个数外,还需要统计包含99的回文数有几个,这可以使用in运算符,不过需要将数字转成字符串。
思路有了,接下来,我们就进入具体的编程实现环节。
三.编程实现
根据上面的思路分析,我们分两步来编写程序:
-
定义函数判断回文数
-
统计回文数个数
1. 定义函数判断回文数
根据前面的思路分析,我们定义函数如下:
代码不多,强调两点:
1). 在拆位过程中,数字会变化,而最后需要和原数字比较,所以,这里借用变量k,来进行拆位,从而保证原数字n不变;
2). 在Python编程中,除法运算符有两个,分别是 / 和 //,此处应该使用//。
2. 统计回文数
有了ispalindrome()函数,接下来就可以循环判断了,编写代码如下:
代码不难,简单说明两点:
1). 输入整数m后,需要计算m位数的最小值和最大值,比如m = 3,最小的三位数是100,最大的三位数是999,在计算start和end的时候,使用了**运算符;
2). 在判断是否包含数字99时,需要将99和数字i都转成字符串。
至此,整个程序就全部完成了,你也可以输入不同的数字来测试效果。
四.总结与思考
本题代码在20行左右,涉及到的知识点包括:
-
循环语句,主要for...in和while;
-
条件语句,尤其是条件的嵌套;
-
函数的定义及使用;
-
拆位算法;
作为经典的回文数问题,实现方法有多种,本题给出了纯数学的解法,关键点在于拆位算法的理解和应用。
拆位是一种常见的基础算法,在编程中应用广泛,其核心是%和//两个运算符的组合。不过这个方法只针对数字有效,如果是字符串,就不能使用这个方法了。
除此之外,为了简化程序,我们采用了函数的编程思想,将回文数的判断过程封装成函数,这正是我们提倡的计算思维,当你具备了计算思维,解决问题的能力会上升一个台阶。
超平老师给你留一道思考题,针对本题采用的计算逆序数的方法,它的局限性有哪些,又该如何解决呢?
你还有什么好的想法和创意吗,也非常欢迎和超平老师分享探讨。
如果你觉得文章对你有帮助,别忘了点赞和转发,予人玫瑰,手有余香😄
需要源码的,可以移步至“超平的编程课”gzh。