一个数如果恰好等于不包含它本身所有因子之和,这个数就称为"完数"。 例如,6的因子为1、2、3,而6=1+2+3,因此6是"完数"。 编程序找出N之内的所有完数,并按下面格式输出其因子
输入格式
N
输出格式
? its factors are ? ? ?
样例输入
复制
1000
样例输出
复制
6 its factors are 1 2 3 28 its factors are 1 2 4 7 14 496 its factors are 1 2 4 8 16 31 62 124 248
本题考验的知识点和技巧较多。
首先,题目要求对一个数进行完数的判断,并且最后还要输出完数的因子。由于判断完数时已经包含了获得因子的步骤,因此考虑将因子存储在一个列表中,这就是代码中哈桑农户iswnum中的re列表的作用。在该函数中,返回两个参数,这也是将该函数中遍历的作用进行合并的体现,如果为了获得因子和判断完数分成两个函数,那么会降低代码的效率,而且实测是超时的。在这个函数中返回的两个参数,用于判断是时候是完数,如果是的话,再将第二个参数列表用于遍历输出。
其次,由于输出格式的限制,导致函数返回的列表无法直接输出,需要从中遍历元素,并且根据print函数的end属性进行输出结果的尾部格式空值,这里end=''表示输出结果不会换行,最后在用一个print()对单独的一行输出结果进行换行。
大致思路如上述,接下来考虑提高代码运行效率的问题。下面的代码是优化后的代码,而没有优化的代码实测是超时的。首先是遍历的次数的优化,根据数学方法,可以不必对输入的数进行从1开始的遍历,由于因子是成对的,可以对其进行平方根,然后分别获得因子对,将这两个因子加到返回的列表中,从而减少迭代次数,提高了效率。另外,由于题目中要求输出结果不包含本身,所以不必要获得因子1的另一对(也就是数本身),但是1显然是要输出的因子,因此可以对返回的列表初始化为包含1的列表,而迭代的条件也可以从2开始。最后,根据题目要求,不要忘记对返回的列表进行排序。
import math
num=int(input())
def iswnum(num):
re=[1]
for i in range(2,int(math.sqrt(num))+1):
if num%i==0:
re.append(i)
re.append(num//i)
if num!=sum(re):
return False,[]
else:
return True,re
for i in range(2,num+1):
flag,l=iswnum(i)
if flag:
print("{wnum} its factors are".format(wnum=i),end='')
for num in sorted(l):
print(" {n}".format(n=num),end='')
print()