从C到Capable-----完美数

☀(day54:C4)

目录

📝题目:

🚩题目分析:

💡解题思路:

🌟解法一:常规解法

🌈代码实现

✨代码注释

🌟解法二:总结法

🌈代码实现


📝题目:

对于一个 正整数,如果它和除了它自身以外的所有 正因子 之和相等,我们称它为 「完美数」。

给定一个 整数 n, 如果是完美数,返回 true;否则返回 false。(1 <= num <= 108)

⭐示例 1:

输入:n = 28

输出:true

解释说明:

1*28 = 28 ,2*14 = 28, 4*7 = 28, 7*4 = 28,14*2 = 28

1+2+4+7+14 = 28.

1, 2, 4, 7, 和 14 是 28 的所有正因子。

⭐示例 2:

输入:n = 7

输出:false

解释说明:

1*7 = 7 , 1不等于7

🚩题目分析:

题中正因子是个专有名词,通俗来讲就是一个数n的正除数,这个除数满足n%除数=0.

💡解题思路:

🌟解法一:常规解法

解题关键是找到数n的所有正因子。

在例1,我们看到2*14 = 14*2 =28,2和14是28的正因子。 4*7 = 7*4 = 28,4和7是28的正因子.

那么当我们找到正因子2和4时,我们用28/2,28/4,即可得到正因子14和7.

值得注意的是如果这时再用28/7 = 4或28/14 = 2,那么将得到两个重复的正因子,我们把所有正因子累加后这个重复的正因子就会影响是否为完美数的判断。

那么我们什么时候停止使用数n/正因子这一步骤呢?

设数n有正因子d1,d2。

由数n/d1 = d2可知,当d1 = d2时使用数n/正因子这一做法就会得到重复正因子

那么d1*d2 = d1*d1 = n。

我们得出结论:当得到一个正因子d时

1.如果d < \sqrt{n}

那么可以使用n/d得出另一个正因子

2.如果d <= \sqrt{n}

那么就停止使用n/d求另一个正因子
 

🌈代码实现

checkPerfectNumber(int num)
{
    if (num == 1)
        return 'False';

    int sum = 1;
    for (int d = 2; d * d <= num; d++) 
    {
        if (num % d == 0) 
        {
            sum += d;
            if (d * d < num)
                sum += num / d;
        }
    }
    return sum == num;
}

✨代码注释

int checkPerfectNumber(int num)
{
    if (num == 1)   // 1除本身外没有正因子
        return 'False';

    int sum = 1;
    /*sum用于记录当前所有正因子相加的值,因为
      除1外每个数都有1这个正因子,所以我们将sum初始化为1*/
    for (int d = 2; d * d <= num; d++)
    {
        if (num % d == 0)
        {
            sum += d;
            // 判断是否可用num/d的方式求另一个正因子
            if (d * d < num)
                sum += num / d;
        }
    }
    /* 如果sum = num说明所有正因子数等于该数本身,
     * 满足sum == num的条件,返回Ture,否则返回False*/
    return sum == num;
}

🌟解法二:总结法

根据欧几里得-欧拉定理,每个偶完全数都可以写成2^{p-1}(2^p-1)的形式,其中 p为素数且 2^p-1为素数。

由于目前奇完全数还未被发现,因此题目范围 [1,10^8]内的完全数都可以写成上述形式。

再[1,10^8]内的完美数一共有如下 5 个:

6, 28, 496, 8128, 33550336
 

🌈代码实现

int checkPerfectNumber(int num)
{
    return num == 6 || num == 28 || num == 496 || num == 8128 || num == 33550336;
}

今天就到这,明天见。🚀

❄❄❄❄❄❄❄❄❄❄❄❄❄❄❄❄❄❄❄❄end❄❄❄❄❄❄❄❄❄❄❄❄❄❄❄❄❄❄❄❄❄❄❄❄❄❄

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

亖夕

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值