分析
对范围内的n个数,双重遍历,将小于n的因子遍历添加进列表,时间复杂度为O(n^2)。对小数可以实现,大数就要改进算法。抛开输出都有的开头的1,其他输出可以看作是
(+ {}).format(lst[i])
遍历时数据范围可以缩减到√n。添加因子时同时添加除数和商。(同时注意这里,对于4*4=16的情况,只添加一个4,也就是
if n*n!=i:
l.append(i//n)
.
同时,可以先添加满因子列表后,sort函数排序,再输出因子分解的和列表。输出格式也可以看作+
号连接了每个元素,使用
" + ".join(str(lst[i])
题目
所谓完数就是该数恰好等于除自身外的因子之和。例如:6=1+2+3,其中1、2、3为6的因子。本题要求编写程序,找出任意两正整数m和n之间的所有完数。
输入格式:
输入在一行中给出2个正整数m和n(1<m≤n≤10000),中间以空格分隔。
输出格式:
逐行输出给定范围内每个完数的因子累加形式的分解式,每个完数占一行,格式为“完数 = 因子1 + 因子2 + … + 因子k”,其中完数和因子均按递增顺序给出。若区间内没有完数,则输出“None”。
解法
超时算法
m,n=map(int,input().split())
cnt=0
for i in range(m,n+1):
lst=[1]#存储数字因子,每次循环清空
alpha_lst=["1"]#存储字符表达式因子,每次循环归1
for j in range(2,i):
if i%j==0:
lst.append(j)
alpha_lst.append("+ "+str(j))
if i==sum(lst):
cnt+=1
print("{} = {}".format(i,' '.join(alpha_lst)))
if cnt==0:
print("None")
改进
import math
m,n=map(int,input().split())
cnt=0
for i in range(m,n+1):
lst=[1]#存储数字因子,每次循环清空
for j in range(2,int(math.sqrt(i)+1)):
if i%j==0:
lst.append(j)
if j*j!=i:#如果是n*n==i 的情况,只添加一个n
lst.append(i//j)#这里使用整数除法,否则后面的因子会有.0
lst.sort()#排序
if i==sum(lst):
cnt+=1
print("{} = ".format(i),end="")
print(" + ".join(str(lst[i]) for i in range(len(lst))))
if cnt==0:
print("None")