2020-10-09

95 篇文章 2 订阅

完全数

完全数(Perfect number),又称完美数或完备数,是一些特殊的自然数。 它所有的真因子(即除了自身以外的约数)的和(即因子函数),恰好等于它本身。
第一个完全数是6,第二个完全数是28,第三个完全数是496,后面的完全数还有8128、33550336等等。 截至2018年,相关研究者已经找到51个完全数。
先简单编一个程序找到前面几个完全数。

from math import ceil

n = int(input("请输入整数N:"))
for i in range(3, n):
    temp = []
    for j in range(1, ceil(i / 2) + 1):
        if i % j == 0:
            temp.append(j)
    cum = 0
    for k in temp:
        cum += k
    if i == cum:
        print("{}=".format(i), end="")
        for k in temp:
            if k != temp[-1]:
                print("{}+".format(k),end="")
            else:
                print("{}".format(k))
D:\Python\Python38\python.exe D:/Python/study/test23.py
请输入整数N:10000
6=1+2+3
28=1+2+4+7+14
496=1+2+4+8+16+31+62+124+248
8128=1+2+4+8+16+32+64+127+254+508+1016+2032+4064

Process finished with exit code 0

8128之后的完全数使用上述程序基本无法等待,时间太长。对上述程序进行优化,首先完全数都是三角形数,其次完全数是偶数且以6或8结束,其三,除6外,其他完全数被3、被9除余1。导入numba提速,程序如下。

from math import ceil
from numba import jit
import time


@jit(nopython=True)
def calc(n):
    s, cum = 0, 0
    for i in range(1, n + 1):
        s += i
    if s % 2 != 0:
        return 0
    if s > 6 and (s % 9 != 1):
        return 0
    if s % 10 != 6 and s % 10 != 8:
        return 0
    for j in range(1, ceil(s / 2) + 1):
        if s % j == 0:
            cum += j
    if s == cum:
        return s
    return 0


t0 = time.time()
for m in range(2, 10000):
    result = calc(m)
    if result != 0:
        print("{}=".format(result), end="")
        for k in range(1, ceil(result / 2) + 1):
            if result % k == 0:
                if k != ceil(result / 2):
                    print("{}+".format(k), end="")
                else:
                    print(k)
print("耗时{}s。".format(time.time() - t0))
D:\Python\Python38\python.exe D:/Python/study/test23.py
6=1+2+3
28=1+2+4+7+14
496=1+2+4+8+16+31+62+124+248
8128=1+2+4+8+16+32+64+127+254+508+1016+2032+4064
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
耗时47.46809959411621s。
Process finished with exit code 0
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值