全网最快的自幂数计算方法 可计算至30位左右

水仙花数是指,一个3位数,它的每位数的3次幂之和等于它本身。水仙花数有4个:153, 370, 371, 407。
而自幂数是水仙花数的扩展,它指的是一个n位数,它的每位数的n次幂之和等于它本身。
大一的时候,C语言老师曾让我们编写程序计算5位数以内的自幂数。当时我们的思路是穷举。例如计算5位数的自幂数,穷举10000~99999内的所有数,找出符合条件的数即可。
但是,若数字很大,例如10位及以上的,这样的算法就支撑不住了。

(关键词:可重复组合)!!!
前几天学习Python,发现可以使用Python的itertools库里的combinations_with_replacement可重复组合方法,大大提升计算速度。
例如,我们要找11位数的自幂数,我们只需从0~9这10个数字里取出11个可重复数字(例如(1,1,1,1,1,1,1,1,1,1,1), (2,2,2,2,2,2,2,2,2,2,2), (1,2,3,4,5,6,7,8,9,0,1)等),构造可重复组合,然后依次对每个组合里的数进行验证,即计算每个数的11次幂之和sum,然后再比较len(str(sum))是否等于11,如果是,则计算sum各位11次幂之和是否为sum,如果是则输出sum。这样利用可重复组合,就不需要从10000000000穷举到99999999999了。果然快很多,已经能跑到29位了。

from itertools import combinations_with_replacement as com
from time import perf_counter as per

def nar(n):
    powarr = []
    for i in range(10):
        powarr.append(i ** n)
    for c in com(range(10), n):
        s = sum(powarr[i] for i in c)
        if len(str(s)) == n and sum(powarr[(ord(i) - 48)] for i in str(s)) == s:
            yield(s)

def main():
    for n in range(1, 40):
        start = per()
        print(n, "位数的自幂数有", sorted(list(nar(n))),"\n耗时:", per() - start, "s\n")

if __name__ == '__main__':
    main()
1 位数的自幂数有 [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
耗时: 0.0005798000000000018 s

2 位数的自幂数有 []
耗时: 8.729999999999849e-05 s

3 位数的自幂数有 [153, 370, 371, 407]
耗时: 0.00029869999999999897 s

4 位数的自幂数有 [1634, 8208, 9474]
耗时: 0.0010171999999999994 s

5 位数的自幂数有 [54748, 92727, 93084]
耗时: 0.0029996999999999975 s

6 位数的自幂数有 [548834]
耗时: 0.0080555 s

7 位数的自幂数有 [1741725, 4210818, 9800817, 9926315]
耗时: 0.019855199999999996 s

8 位数的自幂数有 [24678050, 24678051, 88593477]
耗时: 0.0455187 s

9 位数的自幂数有 [146511208, 472335975, 534494836, 912985153]
耗时: 0.09426789999999999 s

10 位数的自幂数有 [4679307774]
耗时: 0.2000364 s

11 位数的自幂数有 [32164049650, 32164049651, 40028394225, 42678290603, 44708635679, 49388550606, 82693916578, 94204591914]
耗时: 0.5384791 s

12 位数的自幂数有 []
耗时: 0.8060039999999999 s

13 位数的自幂数有 []
耗时: 1.3891908999999998 s

14 位数的自幂数有 [28116440335967]
耗时: 2.5009005 s

15 位数的自幂数有 []
耗时: 4.860277999999999 s

16 位数的自幂数有 [4338281769391370, 4338281769391371]
耗时: 9.4189296 s

17 位数的自幂数有 [21897142587612075, 35641594208964132, 35875699062250035]
耗时: 13.097966700000004 s

18 位数的自幂数有 []
耗时: 22.228616199999998 s

19 位数的自幂数有 [1517841543307505039, 3289582984443187032, 4498128791164624869, 4929273885928088826]
耗时: 35.4807801 s

20 位数的自幂数有 [63105425988599693916]
耗时: 53.20027060000001 s

21 位数的自幂数有 [128468643043731391252, 449177399146038697307]
耗时: 87.7056431 s

22 位数的自幂数有 []
耗时: 130.33216760000002 s

23 位数的自幂数有 [21887696841122916288858, 27879694893054074471405, 27907865009977052567814, 28361281321319229463398, 35452590104031691935943]
耗时: 188.28141319999997 s

24 位数的自幂数有 [174088005938065293023722, 188451485447897896036875, 239313664430041569350093]
耗时: 264.5516602 s

25 位数的自幂数有 [1550475334214501539088894, 1553242162893771850669378, 3706907995955475988644380, 3706907995955475988644381, 4422095118095899619457938]
耗时: 471.38872850000007 s

26 位数的自幂数有 []
耗时: 485.95830150000006 s

27 位数的自幂数有 [121204998563613372405438066, 121270696006801314328439376, 128851796696487777842012787, 174650464499531377631639254, 177265453171792792366489765]
耗时: 613.5496306 s

28 位数的自幂数有 []
耗时: 815.2740477000002 s

29 位数的自幂数有 [14607640612971980372614873089, 19008174136254279995012734740, 19008174136254279995012734741, 23866716435523975980390369295]
耗时: 991.4711625 s
  • 6
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值