HJ56 完全数计算【python3】

题目描述

完全数(Perfect number),又称完美数或完备数,是一些特殊的自然数。
它所有的真因子(即除了自身以外的约数)的和(即因子函数),恰好等于它本身。
例如:28,它有约数1、2、4、7、14、28,除去它本身28外,其余5个数相加,1+2+4+7+14=28。

输入n,请输出n以内(含n)完全数的个数。
数据范围: 1 ≤ n ≤ 5 × 1 0 5 1 \le n \le 5 \times 10^5 1n5×105

输入描述

输入一个数字n

输出描述

输出不超过n的完全数的个数

代码

def is_perfect(number):
    L=[]
    for i in range(1,number//2+1):
        if number%i==0:
            L.append(i)
    if sum(L)==number:
        return 1
    else:
        return 0

while True:
    try:
        n=int(input())
        k=0
        for i in range(3,n+1):
            if is_perfect(i)==1:
                k+=1
        print(k)
    except:
        break

代码解释

  1. 找出数number除本身外的所有因子,判断是否为完全数。由于2是除1外的最小应数,故大于number/2的因数(除自身以外)是不存在的,循环到number/2即可
  2. 由于1,2显然不是完全数,故循环可以从3开始

优化

由于一个数n的因数分布在 n \sqrt n n 的两侧,故可以减少循环次数到 n \sqrt n n
但是需要注意不能把数n本身算在因数列表里
优化后的函数如下。牛客测试用例的运行时间从550ms下降到68ms

def is_perfect(number):
    L=[1]
    for i in range(2,int(number**0.5)+1):
        if number%i==0:
            L.append(i)
            L.append(number//i)
    if sum(L)==number:
        return 1
    else:
        return 0

补充

n最大可输入 5 × 1 0 5 5 \times 10^5 5×105,在牛客运行仍旧超时,因此考虑直接从数学理论入手

完全数公式

完全数公式
由完全数公式可知,对任意一个整数n,若 2 n − 1 2^n-1 2n1是质数,则 ( 2 n − 1 ) 2 n − 1 (2^n-1)2^{n-1} (2n1)2n1是一个完全数。
重新看本题,我们可以先写一个判断是否为质数的函数。由于 2 0 − 1 2^0-1 201 2 1 − 1 2^1-1 211不是质数,因此在range(2,n+1)进行循环,如果当前循环 ( 2 i − 1 ) 2 i − 1 (2^i-1)2^{i-1} (2i1)2i1在输入的范围内,则计数,否则立刻退出循环。最后输出完全数的数量.
牛客通过全部运行用例的时间下降到44ms,自测输入500000可出结果.

import math as ma
# 判断是否为素数
def is_prime(number):
    if number==1:
        return False
    if number==2:
        return True
    for i in range(2,int(ma.sqrt(number))+1):
        if number%i==0:
            return False
    return True


while True:
    try:
        n=int(input())
        k=0
        for i in range(2,n+1):
            if (2**i-1)*pow(2,i-1)<=n:
                if is_prime(2**i-1)==True:
                    k+=1  
            else:
                break    
        print(k)
    except:
        break


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值