Python编程之欧拉计划23

欧拉计划

欧拉计划(Project Euler)。

23、找出所有不能表示为两个过盈数之和的正整数之和

如果一个数的所有真因子之和等于这个数,那么这个数被称为完全数。例如,28的所有真因子之和为1 + 2 + 4 + 7 + 14 = 28,所以28是一个完全数。

如果一个数的所有真因子之和小于这个数,称其为不足数,如果大于这个数,称其为过盈数。

12是最小的过盈数,1 + 2 + 3 + 4 + 6 = 16。因此最小的能够写成两个过盈数之和的数字是24。经过分析,可以证明所有大于28123的数字都可以被写成两个过盈数之和。但是这个上界并不能被进一步缩小,即使我们知道最大的不能表示为两个过盈数之和的数字要比这个上界小。

找出所有不能表示为两个过盈数之和的正整数之和。

分析:题目这句话不太好理解,既然大于28123的数都可以表示为过剩数之和,28123本身也可以表示为两个过盈数之和,这不就证明了所有大于28122的数都可以写成两个过盈数之和了吗?这上界不就缩小了吗?
从解题中可以发现最大的不能表示为两个过盈数之和的数为 20161,也就是所有大于20161的数都可以表示为两个过盈数之和

def d(n):
    return sum(i for i in range(1,n//2+1) if n%i ==0)

# 生成过盈数列表和字典
lst= [a for a in range(12,28124-12) if a < d(a)]
dct = dict.fromkeys(lst, True)

ans = 0
for n in range(1, 28124):
    not_sum = True
    # 若 a 是过盈数,n-a也是过盈数,即 n 为两个过盈数之和
    for a in lst:
        if a < n and dct.get(n - a):
            not_sum = False
            break
    if not_sum:
        ans += n

print(ans)

输出:
4179871

猜你喜欢

转载自blog.csdn.net/lqgeqmbc/article/details/89841690