• Project Euler 23 Non-abundant sums( 整数因子和 )



    题意:
    完全数是指真因数之和等于自身的那些数。例如,28的真因数之和为1 + 2 + 4 + 7 + 14 = 28,因此28是一个完全数。

    一个数n被称为亏数,如果它的真因数之和小于n;反之则被称为盈数。

    由于12是最小的盈数,它的真因数之和为1 + 2 + 3 + 4 + 6 = 16,所以最小的能够表示成两个盈数之和的数是24。通过数学分析可以得出,所有大于28123的数都可以被写成两个盈数的和;尽管我们知道最大的不能被写成两个盈数的和的数要小于这个值,但这是通过分析所能得到的最好上界。

    找出所有不能被写成两个盈数之和的正整数,并求它们的和。

    思路:此题与欧拉21题相似


    /*************************************************************************
        > File Name: euler023.c
        > Author:    WArobot 
        > Blog:      http://www.cnblogs.com/WArobot/ 
        > Created Time: 2017年06月30日 星期五 19时30分05秒
     ************************************************************************/
    
    #include <stdio.h>
    #include <inttypes.h>
    
    #define MAX_N 28123
    
    int32_t isPrime[MAX_N + 10] = {0};		// 记录最小素数幂次方isPrime[24] = 8 (2^3)
    int32_t prime[MAX_N + 10] = {0};		// 记录素数
    int32_t d[MAX_N + 10] = {0};			// 记录整数分解约数和
    int32_t abundantSum[MAX_N + 10] = {0};
    int32_t vis[MAX_N + 10] = {0};
    
    void Init() {
    	for (int32_t i = 2 ; i <= MAX_N ; i++) {
    		if (!isPrime[i]) {
    			isPrime[i] = i;
    			prime[++prime[0]] = i;
    			d[i] = i + 1;
    		}
    		for (int32_t j = 1 ; j <= prime[0] ; j++) {
    			if (i * prime[j] > MAX_N)	break;
    			if (i % prime[j] != 0) {	// 在prime[j]还小于i的最小素因子时
    				isPrime[i * prime[j]] = prime[j];
    				d[i * prime[j]] = d[i] * d[prime[j]];
    			} else {
    				isPrime[i * prime[j]] = isPrime[i] * prime[j];
    				d[i * prime[j]] = d[i] * (isPrime[i] * prime[j] * prime[j] - 1) / (isPrime[i] * prime[j] - 1);
    				break;
    			}
    		}
    	}
    	for (int32_t i = 1 ; i <= MAX_N ; i++) {
    		d[i] -= i;
    		if (d[i] <= i)	continue;
    		abundantSum[++abundantSum[0]] = i;
    	}
    	for (int32_t i = 1 ; i < abundantSum[0] ; i++) {
    		for (int32_t j = i + 1 ; j <= abundantSum[0] ; j++) {
    			if (abundantSum[i] + abundantSum[j] > MAX_N)	continue;
    			vis[abundantSum[i] + abundantSum[j]] = 1;
    		}
    	}
    }
    int32_t main() {
    	Init();
    	int32_t sum = 0;
    	for (int32_t i = 1 ; i <= MAX_N ; i++) {
    		if (vis[i])	continue;
    		sum += i;
    	}
    	printf("%d
    ",sum);
    	return 0;
    }
  • 相关阅读:
    使用别名(CName)记录免费将顶级域名解析到动态IP上
    DataTable 排序
    VS2005中使用MySQL 5.0
    让VS2005用起来更顺手
    PowerBuilder 9.0 Datawindow 导出 pdf 文件
    使用WebClient自动填写并提交ASP.NET页面表单的源代码
    C#中使用条件运算符 (?:)
    如何申请 @msn.com 邮箱
    遇上你是我的缘[转]
    Linux也玩远程桌面(VNC)
  • 原文地址:https://www.cnblogs.com/WArobot/p/7100502.html
Copyright © 2020-2023  润新知