描述
本题要求实现一个计算整数因子和的简单函数,并利用其实现另一个函数,输出最小的N(1 <= N <=8)个完数。所谓完数就是该数恰好等于除自身外的因子之和。例如:6=1+2+3,其中1、2、3为6的因子。
输入格式
一个正整数N,如:1
输出格式
如:6=1+2+3
找出一个数的所有因子,根据这些因子的和是否与该数相等,判定该数是否是完数
def factor(num): # 寻找 num 的所有因子
ls = []
for i in range(1, num):
if num % i == 0:
ls.append(i) # 将num的所有非本身因子加入列表
if sum(ls) == num: # 如果num是完数,返回列表,否则返回False
return ls # 返回包含完数所有因子的列表
else:
return False
找到前n个完数
def oupput(n): # 按格式输出找到的完数
count,i = 1,1 # 计数器置1
while count <= n: # 只寻找前n个完数
if factor(i): # 如果i 是完数,按格式输出
print('{}={}'.format(i, '+'.join([str(x) for x in factor(i)])))
count = count + 1
i = i + 1
完整参考程序为:
def factor(num): # 寻找 num 的所有因子
ls = []
for i in range(1, num):
if num % i == 0:
ls.append(i) # 将num的所有非本身因子加入列表
if sum(ls) == num: # 如果num是完数,返回列表,否则返回False
return ls
else:
return False
def oupput(n): # 按格式输出找到的完数
count,i = 1,1 # 计数器置1
while count <= n: # 只寻找前n个完数
if factor(i): # 如果i 是完数,按格式输出
print('{}={}'.format(i, '+'.join([str(x) for x in factor(i)])))
count = count + 1
i = i + 1
if __name__ == '__main__':
n = int(input()) # 此处要求输入为正整数
oupput(n) # 调用输出函数
这个题目的计算量比较大,如果想找到更多的完数,需要使用一些算法,例如数学方法 :
6=1+2+3 (22-1)+(22-1)1=2(22-1)
28=1+2+4+7+14 (23-1)+(23-1)*(22-1)=22*(23-1)
496=1+2+4+8+16+31+62+124+248 (25-1)+(25-1)(24-1)=(24)(25-1)
8128=1+2+4+8+16+32+64+127+254+508+1016+2032+4064 (27-1)+(27-1)*(26-1)=(26)*(27-1)
33550336= 1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8191, 16382, 32764, 65528, 131056, 262112, 524224, 1048448, 2096896, 4193792, 8387584, 16775168]
如果 m 是素数,且 2 m - 1 也是素数,那么2 (m - 1) (2 * m - 1) 是一个完数。
判断素数的函数 :
def isPrime(n): # 判断素数的函数
if n < 2:
return False # 0和1不是素数
for i in range(2, int(n**0.5)+1):
if n % i == 0:
return False
else:
return True
判断完全数的函数:
def isPerfect(m): # 判断完数的函数
if isPrime(m) and isPrime(2 * *m - 1): # 如果 m 和 2 ** m - 1 都是素数
s = 2 ** (m - 1) * (2 ** m - 1) # 2 ** (m - 1) * (2 ** m - 1) 是一个完数
ls.append(s) # 完数加入到列表中
i=0
while s % 2 ==0: # 对完数进行分解因数
s=s // 2
factor.append(s) # s // 2 和 2 ** i 次方同时是因子
factor.append(2 ** i)
# 496=1+2+4+8+16+ 31 +62+124+248
i = i + 1
if len(factor) % 2 == 0: # 加入最后一个因子 2 ** i
factor.append(2 ** i)
return s
else:
return False
完整参考代码,以下代码可以完成前9个完数的输出:
def isPrime(n): #判断素数的函数
if n < 2:
return False #0和1不是素数
for i in range(2, int(n**0.5)+1):
if n % i == 0:
return False
else:
return True
def isPerfect(m): #判断完数的函数
if isPrime(m) and isPrime(2**m-1):
s = 2**(m-1)*(2**m-1)
ls.append(s)
i=0
while s%2 ==0:
s=s//2
factor.append(s)
factor.append(2**i)
i = i+1
if len(factor)%2==0:
factor.append(2 ** i)
return s
else:
return False
if __name__ == '__main__':
n = int(input()) # 此处要求输入为正整数
ls = []
count, num = 0, 1
while count < n:
factor = []
if isPerfect(num):
factor.sort()
print('{}=1'.format(ls[count]), end='')
for j in factor[1:]:
print("+{}".format(j), end='')
count = count + 1
print()
num = num + 1
还有一种更高效的方法,可以完成前14个完数的输出:
# 公管大数据1901班康佳丽
n = int(input())
def isPrime(N):
if N < 4: return N > 1
if ((N & 1) == 0): return False
i = 3
while i * i <= N :
if (N % i) == 0 :
return False
i += 2
return True
def primality(N, M):
if N == 2 :
return True
s = 4
for i in range(0, N - 2) :
s = (s * s - 2) % M
return s == 0
def findPerfectNumber() :
count = 0
ls=[]
for i in range(2, 5000):
M = (1 << i) - 1
t = M << (i-1)
# 当p为素数且梅森数2^p-1为素数时2^(p-1)*(2^p-1)为完全数
if isPrime(i) and primality(i,M) :
count += 1
ls.append(t)
if count>n-1:
return(ls)
Lis=findPerfectNumber() # 得到包含前n位完数的列表
def Yinzi(s): # 获取每个完数的因子
i=0
while s%2 ==0:
s=s//2
factor.append(s)
factor.append(2**i)
i = i+1
if len(factor)%2==0:
factor.append(2 ** i)
return factor
count = 0
ls = []
for i in Lis:
factor=[]
factor = Yinzi(i)
factor.sort()
print('{}=1'.format(Lis[count]), end='')
for j in factor[1:]:
print("+{}".format(j), end='')
count = count + 1
print()