The Preliminary Contest for ICPC China Nanchang National

A - PERFECT NUMBER PROBLEM

Write a program to output the first 5 perfect numbers. A perfect number is defined to be a positive integer where the sum of its positive integer divisors excluding the number itself equals the number.
For example: 1+ 2 + 3 = 6, and 6 is the first perfect number.
There is no input for this problem.

一、有关完数(Perfect number)的定义:

In number theory, a perfect number is a positive integer that is equal to the sum of its proper positive divisors, that is, the sum of its positive divisors excluding the number itself (also known as its aliquot sum).
它所有的真因子(即除了自身以外的约数)的和(即因子函数),恰好等于它本身。如果一个数恰好等于它的因子之和,则称该数为“完全数”。

Equivalently, a perfect number is a number that is half the sum of all of its positive divisors (including itself).
同样,一个完全数是它所有正因子(包括它自己)之和的一半。

二、前六个完全数

1……6
2……28
3……496
4……8,128
5……33,550,336
6……8,589,869,056

(目前为止一共发现48个,且全为偶数)

三、有关完数的性质

1 - 所有完数均为三角形数
所有的完全数都是三角形数。例如:6=1+2+3;28=1+2+3+…+6+7;496=1+2+3+…+30+31;8128=1+2+3…+126+127。
这些数量的(石子),都可以排成三角形

一定数目的点或圆在等距离的排列下可以形成一个等边三角形,这样的数被称为三角形数。古希腊著名科学家毕达哥拉斯把数1,3,6,10,15,21……这些数量的(石子),都可以排成三角形,像这样的数称为三角形数。
把1.4.9.16.…这样的数称为正方形数。

在这里插入图片描述

2 - 可以表示成连续奇立方数之和
可以表示成连续奇立方数之和。除6以外的完全数,都可以表示成连续奇立方数之和,并规律式增加。
在这里插入图片描述

四、完数的推导

在这里插入图片描述

梅森数(Mersenne number)又称麦森数,是指形如2^p-1的正整数,其中指数p是素数,常记为Mp 。若其是素数,则称为梅森素数。
用因式分解法可以证明,若2n-1是素数,则指数n也是素数;反之,当n是素数时,2n-1(即Mp)却未必是素数。前几个较小的梅森数大都是素数,然而梅森数越大,梅森素数也就越难出现。

M1 - M6

序号p梅森素数(2^p - 1)位数
1231
2371
35312
471273
51381914
6171310716

五、编程实现

这里有一个很重要的问题,最开始我从分解质因数的角度出发,但是开始补这道题的时候发现完数里说的是positive integer divisors(正整数因子),也就是它所有的分解可能(因子组合),而不是所有质因子相加。
比如,28是完数,28 = (1 + 28 + 2 + 14 + 4 + 7) / 2,这里面并不是分解找到质因数再相加。

#include <iostream>
#include <cmath>
using namespace std;
 /**很重要的一个点,完数的因子分解不是全部分解为质因子!**/
int temp, sum, total;
int main()
{
    //找出前5个完数
    cout << 6 << endl; //6已知,不再去判断,减少时间


    for(int i = 7; total < 5 ;i++) //当total = 5的时候break即可,不必设置i的条件
    {
        sum = 1;//根据分析 positive integer divisor 肯定是包含1的 不论什么数
        for(int j = 2;j < sqrt(i);j++)
        {
            if(i % j == 0 && i != j)
            {
                sum += j;
                temp = i / j;
                sum += temp;
            }
        }
        if(sum == i)
        {
            total++;
            cout << i << endl;
        }
    }

    return 0;
}

先暴力一发,会跑好久,不过第五个数还是能跑出来的。(放着没管它的我去吃了趟午饭,吃完回来发现第五个跑出来了-_-|||)

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值