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) | 位数 |
---|---|---|---|
1 | 2 | 3 | 1 |
2 | 3 | 7 | 1 |
3 | 5 | 31 | 2 |
4 | 7 | 127 | 3 |
5 | 13 | 8191 | 4 |
6 | 17 | 131071 | 6 |
五、编程实现
这里有一个很重要的问题,最开始我从分解质因数的角度出发,但是开始补这道题的时候发现完数里说的是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;
}
先暴力一发,会跑好久,不过第五个数还是能跑出来的。(放着没管它的我去吃了趟午饭,吃完回来发现第五个跑出来了-_-|||)