欧拉计划 第二十三题

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. !

完美数字是一个数字,其正确除数的总和恰好等于数字。例如,28的适当除数之和为1 + 2 + 4 + 7 + 14 = 28,这意味着28是一个完美数。

如果n的适当除数之和小于n,则n被称为不足,如果该和超过n则称为n。

由于12是最小的有限数,1 + 2 + 3 + 4 + 6 = 16,可以写成两个有限数之和的最小数是24.通过数学分析,可以看出所有整数都大于28123可以写成两个数字的总和。然而,即使已知不能表示为两个充裕数的总和的最大数小于该限制,也不能通过分析进一步减小该上限。

找到所有正整数的总和,这些正整数不能写为两个数字的总和。

思路

1.一个正整数n被分解成质数相乘,如12 = 2(2)*3; p1(a1) p2(a2)p3(a3);

2.因子个数=(a1+1)(a2+1)(a3+1),如12的因子个数=(2+1)(1+1)=6;

3.F(A * B)=F(A)*F(B);

4.因子和:Eg 12因子和=28=(1+3)(1+2 + 2*2)

Sum_factor(n) = (p1^0 + p1^1 + p1 ^2 + ... + p1^a1)*(P2^0 + p2^1 +...+p2^a2) *... *(pn^0 + pn ^1 +...+ pn^an)

= 求乘[1-pi^(ai + 1)]/1-pi;

F(B) = F(A)/{[1-p1^ (a1+1)]/1-p1}*{[1-p1^(a1+2)]/1-p1}=F(A) * [1 - p1^(a1+2)]/[1 - p1^(a1+1)];

#include <stdio.h>

#define max 28123

int prime[max + 5] = {0};
int isprime[max + 5] = {0};
int Sum_factor[max + 5] = {0};
int num[max + 5] = {0};

int main(){
	Sum_factor[1] = 0;
	for(int i = 2; i <= max; i++){//Sum_factor存放的是各个因子和;
		if(!isprime[i]){
			isprime[i] = i;
			prime[++prime[0]] = i;
			Sum_factor[i] = i + 1;
		}
		for(int j = 1; j <= prime[0]; j++){
			if(i * prime[j] > max) break;
			if(i % prime[j] == 0){
				isprime[i * prime[j]] = isprime[i] * prime[j];
				Sum_factor[i * prime[j]] = Sum_factor[i] * (isprime[i] * prime[j] * prime[j] - 1) / (isprime[i] * prime[j] - 1);
				break;
			}else{
				isprime[i * prime[j]] = prime[j];
				Sum_factor[i * prime[j]] = Sum_factor[i] * Sum_factor[prime[j]];
			}
		}
	}
	Sum_factor[0] = 0;//Sum_factor[0]存放的是充裕数的个数;
	for(int i = 0; i <= max; i++){
		Sum_factor[i] -= i;
		if(Sum_factor[i] > i) Sum_factor[++Sum_factor[0]] = i;//Sum_factor[i]中存放的是第i个数是充裕数;与之前的线性筛一样;
	}
	for(int i = 1; i <= Sum_factor[0]; i++){
		for(int j = i; j <= Sum_factor[0]; j++){
			if(Sum_factor[i] + Sum_factor[j] > max) break;
			num[Sum_factor[i] + Sum_factor[j]] = 1;//把能使两个充裕数求和的数标记为1;
		}
	}
	int sum = 0;
	for(int i = 0; i <= max; i++){
		if(!num[i]) sum += i;//未被标记的数就可以累加起来啦;
	}
	printf("%d\n", sum);
	return 0;
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值