• Project Euler 21 Distinct primes factors( 整数因子和 )



    题意:
    记d(n)为n的所有真因数(小于n且整除n的正整数)之和。
    如果d(a) = b且d(b) = a,且a ≠ b,那么a和b构成一个亲和数对,a和b被称为亲和数。

    例如,220的真因数包括1、2、4、5、10、11、20、22、44、55和100,因此d(220) = 284;而284的真因数包括1、2、4、71和142,因此d(284) = 220。

    求所有小于10000的亲和数的和。

    整数因子和:

    <font color = red , size = 5 >**以下图片仅供学习!图片来源为海贼科技:

    http://www.haizeix.com/

    **








    My Code :

    /*************************************************************************
        > File Name: euler021.c
        > Author:    WArobot 
        > Blog:      http://www.cnblogs.com/WArobot/ 
        > Created Time: 2017年06月30日 星期五 16时47分13秒
     ************************************************************************/
    
    #include <stdio.h>
    #include <inttypes.h>
    
    #define MAX_RANGE 10000
    
    int32_t isPrime[MAX_RANGE + 10] = {0};		// 存放数字i的最小素因子幂次项,例如isPrime[24] = 8 
    int32_t prime[MAX_RANGE + 10] = {0};		// 素数表
    int32_t d[MAX_RANGE + 10] = {0};			// 存放数字i约数的和
    
    void Init() {
    	for (int32_t i = 2 ; i <= MAX_RANGE ; i++) {
    		if (!isPrime[i]) {
    			isPrime[i] = i;
    			d[i] = i + 1;
    			prime[++prime[0]] = i;
    		}
    		for (int32_t j = 1 ; j <= prime[0] ; j++) {
    			if (i * prime[j] > MAX_RANGE)	break;
    			if (i % prime[j] == 0) {		// 如果prime[j]是i的最小素因子,那么就相当于在原来的基础上增加了一个最小的素因子,所以得改变原来的d[]
    				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;
    			} else {
    				isPrime[i * prime[j]] = prime[j];		// 因为prime[j]比i的最小素因子还小(线性筛原理),所以更新i * prime[j] 的最小素因子为prime[j]	
    				d[i * prime[j]] = d[i] * d[prime[j]];	// i 和 prime[j]互素所以可以用约数和定理:若正整数A、B互素 C = A*B 则有F(C) = F(A) * F(B)(F(x)为x的约数和)
    			}
    		}
    	}
    }
    int32_t main() {
    	Init();
    	for (int32_t i = 1 ; i <= MAX_RANGE ; i++) {
    		d[i] -= i;		// 并不包含自身
    	}
    	int32_t sum = 0;
    	printf("d[220] = %d
    ",d[220]);
    	printf("d[284] = %d
    ",d[284]);
    	for (int32_t i = 1 ; i <= MAX_RANGE ; i++) {
    		if (d[i] > MAX_RANGE) 	continue;
    		if (d[d[i]] == i && d[i] != i) {	// 注意题目中要求 d(a) = b,d(b) = a,a!=b 
    			sum += i;
    		}
    	}
    	printf("%d
    ",sum);
    	return 0;
    }
  • 相关阅读:
    浮点数
    opencv笔记-GFTTDetector
    有向图与关联矩阵
    亚像素角点
    字符串格式化输出
    字符串表示与转换
    Bresenham算法
    罗德里格斯公式
    模型调参
    jave 逻辑运算 vs 位运算 + Python 逻辑运算 vs 位运算
  • 原文地址:https://www.cnblogs.com/WArobot/p/7100203.html
Copyright © 2020-2023  润新知