一道奥赛Python题的四种解法

2021-10-15 16:43牟晓东
电脑报 2021年24期
关键词:字符串数位列表

牟晓东

请用1-6六个数字组成一个六位数abcdef.其中不同的字母代表1-6中不同的数字,要求:ab是2的倍数.abc是3的倍数.abcd能被4整除.abcde能被5整除.abcdef是6的倍数

请问:这样的六位数有几个?各是多少?

解法1:借助字符串求解

借助字符串方法通过多列表求解。首先建立第一个空列表my_listl:“my_listl=¨”,通过构建循环“for l in range(123456,654321):”控制从最小数123456到最大数654321依次遍历,同时根据题意进行第一次数据过滤:“if int (i//10000)%2==0 andint

(i//1000)% 3==0 and int( 111100)%4==0 andint(i//10)%5==0 andi%6==0”,即从该数中分别取出高二位ab、高三位abc……对2、3等进行整除判断,如果五个条件同时满足的话,则将该整型数据转换为字符串后追加至my_listl中:“my_listl.append(str(1))”。

接着建立第二个空列表my_list2,通过构建循环“for words in my_listl:“对刚刚得到的列表my_listl进行遍历,第二次数据过滤的条件是“if '0'not in words and '7' not in words and '8' not inwords and '9' not in words:”,即去除其中包含有非“123456”字符(0、7、8、9)的“不合法”数据,将满足要求的数据再次通过append方法追加至列表my_list2中:“my_list2append( words)”。

再建立第三个空列表my_list3,对列表my_list2进行遍历:“for words in my_list2:”,将每个数据依次保存至集合my_set中:“my_set= set

此时,在列表my_list3中所保存的数据已经是符合要求的数据了,但其类型是字符串而非真正的整型数据,因此再建立第四个列表my_list4,通过“forwords in my_list3:”对列表my_list3进行遍历,将各数据通过int()函数转换为整型数据后追加至列表my_list4中:“my_list4.append(int(words》”。

最后,使用一条print()语句将结果输出:“print(‘这樣的六位数有,len( my_list4),‘个,,‘它们是:,my_list4)”。

运行程序,得到最终运算结果:

“这样的六位数有2个,它们是:[123654,321654]"<如图1)。

在Spyder编辑器右上方的“变量管理器”中也不难发现,程序在一步一步运行时的四个列表中的数据变化,从最开始的my_listl有707个数据,然后是my_list2已经被“过滤”、只保留50个数据,而最终的my_list3和my_list4则只有两个符合题意要求的数据。

解法2:利用集合“去重”

借助取整除与取余求各数位,再进行范围限定和集合“去重”。首先建立空列表my_list,同样是先进行五个整除条件的第一次数据过滤操作,范围仍然是从123456至654321:将符合条件的数据追加至列表my_list中:“my_list.append(i)”。

接着对列表my_list进行数据遍历:“for num inmy_list”,利用Python中的数学取整除运算“//t和取余运算“%”,再结合int()取整函数,分别取出每个六位数的各数位,从高位到低位依次赋值给a、b、c、d、e和f六个变量;然后进行判断:“if O

运行程序,得到最终运算结果:“123654和321654”(如图2)。

解法3:多层循环嵌套

先层层循环嵌套确保各数位相异再进行整除过滤。首先建立空列表my_list,从最高位a进行层层循环嵌套:“for a in range(l,7)”,控制每个数位从最小数1至最大数6递增;接着进入下一层循环,构建次高位b:“for b iniange(1,7)”,此时要与它的上一层循环(高位a)进行是否相异的判断:“ifb! =a:”,该条件成立的话才继续进入下一层循环:“for c iniange(1,7)”,同样要进行三个变量的两两相异判断,由于上层已经进行了a、b判断,因此只进行c与a、c与b的相异判断:“if c! =a and c! =b”;按照这个规律一直向内循环,一直进行到最低位变量f,f要与它的外层循环变量e、d、c、b和a都相异:“if!=a and f!=bandf! =candf! =dandf! =e”,条件均满足的话,构建符合条件的数据保存至变量num中:“num=a*100000+b*lOOOO+c*lOOO+d*100+e*10+f”,并且将它追加至列表my_list中。

此时,已经得到了一组各数位均不相同的六位数,再对列表my_list的数据进行遍历:“for num inmy_list”,判断条件即为题意中的五个整除条件:“if int(num//10000)%2==0and int( num//1000)% 3==0 and int (num//100)% 4==0and int (num//10)%5==0 and num% 6==0“;符合该条件的话,直接打印输出即可:“print( num)”。

运行程序,得到最终运算结果:“123654和321654”(如图3)。

解法4:借助itertools迭代器模块

借助于Python的itertools迭代器模块可以比较方便地解决本题,本法代码量少、技巧性较高,中学生理解起来的难度也较大。

首先导入itertools,建立一个只包含1-6六个数字的数列array:“array=【1,2,3,4,5,6]";接着建立变量pailie,其值为对数列array中的数据进行所有组合排列:“pailie= iterr,ools.permutations( array)”;此时得到的数据已经是各数位均相异的数据,不必再像上面的三种方法进行集合数据去重或条件限定的判断;然后对变量pailie中的数据进行遍历:“for xinpailie”,同时使用map()函数、int()函数、join方法等进行数据构建,保存至变量num中:“nuni= im(¨'.join( rnap( str,x》)”;接着,同样是使用题意中的五个整除条件构建if语句:“if in“nurn//10000)%2==0 and int (num//1000)% 3==0 and int( num//100) %4==0 and int( num//10) %5==0 andnum%6==0“,符合该条件即为题目所求的数据,最后将变量num打印输出即可:“print( num)”。

运行程序,同样也是得到了最终运算结果:“123654和321654”(如图4)。

猜你喜欢
字符串数位列表
扩列吧
认识数位
一种基于PowerBuilder环境字符串相似度算法
列表法解分式方程问题探索
SQL server 2008中的常见的字符串处理函数
倍增法之后缀数组解决重复子串的问题
找规律巧解题
最简单的排序算法(续)
列表画树状图各有所长
2011年《小说月刊》转载列表