曾经沧海难为水,除却巫山不是云。|

Joey-Wang

园龄:4年3个月粉丝:17关注:0

5.5 质因数分解

5.5 质因数分解

http://codeup.hustoj.com/contest.php?cid=100000592

E 完数与盈数

image-20200718163149588

题目解析

⚠️完美数的定义是其不等于本身的因子之和等于其本身,也就是说 完美数所有因子和等于本身的2倍

大体解题思路:

  1. 要得到一个数n的各因子之和,要先得到n的所有质因数。则将问题转换为求解n的所有质因数
image-20200718163549613
  1. 要求解n的质因数,首先要对素数打表,此处为尽可能节约时间,采用埃式筛法【O(nloglogn)】

PS:若只需求一个数的所有因子个数,则不用写出结构体factor,只需统计所有cnt的个数即可(可以简化代码)

对代码的解释

  1. 定义prime记录所有的素数,pNum为素数个数;bool型数组p中 p[i]表示i是否为素数,false为是,true为否。

    【此为埃式筛法的内容】

  2. factor表示一个质因子,x为质因子具体数值,cnt为此质因子的个数,求解质因子步骤大致为:

    • 枚举1~sqrt(n)范围内的所有素数p,判断p是否为n的因子
      • 若是,则给fac数组中添加质因子p,并初始化个数为0;然后若p还是n的因子,则让n不断除以p并cnt++,直到p不再是n的因子
    • 若👆步骤结束后n仍大于1,表明n有且仅有一个大于sqrt(n)的质因子(可能为n本身),将之加入fac数组并令个数为1
  3. 求解完质因子后,可通过公式算出n的所有因子之和sum。

  4. 若sum = n + n,则为完数;若sum > n + n,则为盈数。

    【用perfect数组记录所有完数,len1为完数个数;用notpf数组记录所有盈数,len2位盈数个数。】

代码

#include <cstdio>
#include <cmath>

#define MAX 100
int prime[MAX], pNum = 0;
bool p[MAX] = {false};
int perfect[MAX], len1 = 0, notpf[MAX], len2 = 0;
struct factor {
    int x, cnt;
} fac[10];
int fNum;

void find_prime() {
    for (int i = 2; i < MAX; i++) {
        if (!p[i]) {
            prime[pNum++] = i;
            for (int j = i + i; j < MAX; j += i)
                p[j] = true;
        }
    }
}

int get_factor_sum(int n) {
    fNum = 0;
    int sqr = sqrt(n);
    int sum = 1;
    for (int i = 0; i < pNum && prime[i] <= sqr; i++) {  //⚠️一定是<=sqr,且sqr的数求解要写外面,因为循环中n一直在变
        if (n % prime[i] == 0) {
            fac[fNum].x = prime[i];
            fac[fNum].cnt = 0;
            while (n % prime[i] == 0) {
                fac[fNum].cnt++;
                n /= prime[i];
            }
            fNum++;
        }
        if (n == 1) break;
    }
    if (n != 1) {
        fac[fNum].x = n;
        fac[fNum].cnt = 1;
        fNum++;
    }
    for (int i = 0; i < fNum; i++) {
        sum *= (int) (1 - pow(fac[i].x, fac[i].cnt + 1)) / (1 - fac[i].x);
    }
    return sum;
}

void find_perfect() {
    find_prime();
    for (int i = 2; i <= 60; i++) {
        int temp = get_factor_sum(i);
        if (temp == i + i) perfect[len1++] = i;
        else if (temp > i + i) notpf[len2++] = i;
    }
}

int main() {
    find_perfect();
    printf("E: ");
    for (int i = 0; i < len1; i++) {
        printf("%d ", perfect[i]);
    }
    printf("G: ");
    for (int i = 0; i < len2; i++) {
        printf("%d ", notpf[i]);
    }
    return 0;
}

本文作者:Joey-Wang

本文链接:https://www.cnblogs.com/joey-wang/p/14541171.html

版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。

posted @   Joey-Wang  阅读(123)  评论(0编辑  收藏  举报
点击右上角即可分享
微信分享提示
评论
收藏
关注
推荐
深色
回顶
展开