▼页尾

[Project Euler] Problem 23

A perfect number is a number for which the sum of its proper divisors is exactly equal to the number. For example, the sum of the proper divisors of 28 would be 1 + 2 + 4 + 7 + 14 = 28, which means that 28 is a perfect number.

A number n is called deficient if the sum of its proper divisors is less than n and it is called abundant if this sum exceeds n.

As 12 is the smallest abundant number, 1 + 2 + 3 + 4 + 6 = 16, the smallest number that can be written as the sum of two abundant numbers is 24. By mathematical analysis, it can be shown that all integers greater than 28123 can be written as the sum of two abundant numbers. However, this upper limit cannot be reduced any further by analysis even though it is known that the greatest number that cannot be expressed as the sum of two abundant numbers is less than this limit.

Find the sum of all the positive integers which cannot be written as the sum of two abundant numbers.

如果一个数所有除自身以外的所有因数之和等于这个数,我们就称这个数为完美数

如果和大于那个数,我们就称这个数为“胖数”(我自己瞎起的名字);

题目中给了一个结论:所有大于28123的数都能表示成两个“胖数”的和

我们要求所有不能表示为两个“胖数”之和的正整数的和

我们先来按照最长规的思路,我们对于整数n,可以表示为n/2对正整数之和,如果其中恰有一对都是“胖数”

那么整数n能表示为两个“胖数”之和

我们找出所有不能表示为两个“胖数”的数,然后求其和即可

但这个思路会做很多无用功,例如 40 = 20+20 ,41 = 20+21;

在验证41的时候,我们要调用函数判断20是不是“胖数”,而这一过程是我们在验证40时就做过的

我们也许会想到把20是不是“胖数”的结果保存起来

如果我们从1一直验证28123,那将是一个n*n的时间复杂度的过程

我们不妨换一个思路,我们先求出所有小于28123的“胖数”,然后再由“胖数”剔除所有能表示为两个“胖数”之和的数

求剩下的数的和就可以了

#include <iostream>
#include
<cmath>
#include
<vector>
usingnamespace std;

constint MAX =28123;

bool isAbundant(int tmp){
int sum =0;
int i;

for(i=1; i<sqrt(tmp); i++){
if(tmp%i ==0){
sum
= sum+i+tmp/i;
}
}

if(i*i == tmp){
sum
+= i;
}
return sum-tmp>tmp;
}

int main()
{
int sum =0;
int flag[MAX] = {0};
vector
<int> abundant;

for(int i=0; i<MAX; i++){
if(isAbundant(i)){
abundant.push_back(i);
}
}

for(int i=0; i<abundant.size(); i++){
for(int j=i; j<abundant.size(); j++){
if(abundant[i]+abundant[j]-1< MAX){
flag[abundant[i]
+abundant[j]-1] =1;
}
else{
break;
}
}
}

for(int i=0; i<MAX; i++){
if(flag[i] ==0){
sum
+= i+1;
}
}

cout
<< sum << endl;
return0;
}

前面说得太啰嗦了,不知道有没有什么其他的好方法

posted @ 2011-03-06 23:22  xiatwhu  阅读(623)  评论(1编辑  收藏  举报
▲页首
西