【小算法整理】- 质因子分解

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_26398495/article/details/82192117

质因子分解

练习题: PAT. A1059 ||


| 存储结构

  • 定义结构体factor存放质因子及其个数
//质因数 结构体 
struct Factor {
    int x; //质因子
    int num; //个数 
}fac[10]; //int范围内,10位够用了

考虑到 2x3x5x7x11x13x17x19x23x29 就已经超过了int范围,因此对一个int范围内的数来说,fac[]数组的大小只需开到10就可以了!

| 结论:

  • 对于一个正整数 N,如果它存在 [2,N] 的质因子,则要么这些质因子全部小于等于 sqrt(N),要么只存在一个大于sqrt(N)的质因子,其余质因子全部小于等于sqrt(N);

| 求解思路:获取质因数

  • 0、令 remain = N
  • 1、枚举 1 ~ sqrt(N) 范围内所有质因子 P,判断 P 是否是N的质因子:
    是:循环相除并记录 ;
    否:跳过;
  • 2、如果以上步骤结束,仍然有 remain > 1,则说明 N 有且仅有一个大于 sqrt(N) 的质因子,
    加入这个质因子即可!(就是当前剩下的部分remain

| 扩展点:

  • 如果要求一个正整数N的因子个数(注:因子),只需对其质因子分解,得到个质因子的Pi的个数分别为e1e2、… ek,于是N的因子个数就是(e1+1) * (e2+1) * … * (ek+1)
    【原因:每个质因子Pi都可以选择出现0次、1次、…、ei次,共ei+1种可能,组合起来即为上述答案】
  • 同理,所有因子之和为:(1+P1+P1^2+…+P1^e1) * (1+P2+P2^2+…+P2^e2)* … *(1+Pk+Pk^2+…+Pk^ek) ;

| 具体实现:

const int maxn = 100010; //int范围内,素数表开到10^5就够用了!

int prime[maxn], pNum = 0; //素数表, 素数个数

//质因子 结构体 
struct Factor {
    int x; //质因子 
    int num; //个数
}fac[10]; //int范围内,10位够用了

//判断素数 
bool isPrime( int k) {
    if(k <= 1) return false;
    int sqt = sqrt(1.0 * k);
    for( int i = 2; i <= sqt; i++) {
        if(k % i == 0)
            return false;
    }
    return true;
}

//保存素数表 
void get_prime(int n) {
    for(int i = 2; i < n; i++)
        if(isPrime(i)){
            prime[pNum++] = i;
        }
}

//保存质因子信息
int get_factor(int N) {
    int count = 0, remain = N;

    int sqt = (int)sqrt(1.0 * N);
    for(int i = 0; i < pNum && prime[i] <= sqt; i++) {

        if(remain % prime[i] != 0) continue; //不是因子

        fac[count].x = prime[i]; //记录该因子
        fac[count].num = 0;
        while(remain % prime[i] == 0) { //一次性取尽
            fac[count].num++;  //保存质因子信息 
            remain /= prime[i];
        }

        count++;  //不同质因子个数+1

        if(remain == 1) break; //及时退出循环,节省时间
    }

    if(remain > 1) { //最后不为1的部分(无法被根号N内的质因子除尽)
        fac[count].x = remain;
        fac[count++].num = 1;
    }
    return count;
}

/*质因子分解给定整数,并输出*/
int main() {
    int N;
    get_prime(maxn);

    scanf("%d", &N);        
    int fac_num = get_factor(N); //质因子分解

    //输出    
    for(int i = 0; i < fac_num - 1; i++) {
        if(fac[i].num != 1) printf("%d^%d*", fac[i].x, fac[i].num);
        else printf("%d*", fac[i].x);
    }
    if(fac[fac_num-1].num != 1) printf("%d^%d\n", fac[fac_num-1].x, fac[fac_num-1].num);
    else printf("%d\n", fac[fac_num-1].x);

    return 0;
} 

猜你喜欢

转载自blog.csdn.net/qq_26398495/article/details/82192117