PAT-A 1059 Prime Factors (25 point(s))

本文介绍了一种有效的质因数分解算法,通过线性筛法求取素数表,进而分解给定正整数的所有质因数。算法考虑了[2, n]范围内质因子的特性,确保了分解效率。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1059 Prime Factors (25 point(s))

Given any positive integer N, you are supposed to find all of its prime factors, and write them in the format N = p​1​​​k​1​​​​×p​2​​​k​2​​​​×⋯×p​m​​​k​m​​​​.

Input Specification:

Each input file contains one test case which gives a positive integer N in the range of long int.

Output Specification:

Factor N in the format N = p​1​​^k​1​​*p​2​​^k​2​​**p​m​​^k​m​​, where p​i​​'s are prime factors of N in increasing order, and the exponent k​i​​ is the number of p​i​​ -- hence when there is only one p​i​​, k​i​​ is 1 and must NOT be printed out.

Sample Input:

97532468

Sample Output:

97532468=2^2*11*17*101*1291

思路: 对一个正数n来说,如果它存在[2, n]范围内的质因子,要么这些质因子全部小于等于sqrt(n),要么只存在一个大于sqrt(n)的质因子,这样便可以开数组利用筛法求素数表,然后遍历素数表分解质因数.

#include <cstdio>
#include <cmath>
#include <climits>

/*
    对一个正数n来说,如果它存在[2, n]范围内的质因子,
    要么这些质因子全部小于等于sqrt(n)
    要么只存在一个大于sqrt(n)的质因子
    这样便可以开数组利用筛法求素数表
*/
const int maxn = (int)sqrt(1.0 * INT_MAX) + 10;//计算素数表的范围
int prime[maxn];//找到的素数
bool flag[maxn];//标记是否是素数
int pnum = 0;//maxn范围内素数的个数

struct factor
{
    int f;// 素因数
    int cnt;// 素因数出现的次数
}fac[10];
int fnum = 0; // 不同素因数的个数

int main()
{
    //线性筛法求2~maxn内的素数表
    for(int i = 0; i < maxn; i++)
        flag[i] = true;//初始默认所有数字为素数
    for(int i = 2; i <= maxn; i++)
    {
        if(flag[i])
            prime[pnum++] = i;//保存找到的素数
        for(int j = 0; j < pnum && prime[j] * i <= maxn; j++)
        {   //晒去以i为最大因数的合数
            flag[prime[j] * i] = false;
            if(i % prime[j] == 0)
                break;//当前素数为i的最小素因数
        }
    }

    int n;//需要分解质因数的数
    scanf("%d", &n);
    if(n == 1)
    {
        printf("1=1\n");
        return 0;
    }
    int sqr = (int)sqrt(1.0 * n);
    printf("%d=", n);//在改变前输出
    //遍历2~sqrt(n)之间的素数并计算是否是素因数
    for(int i = 0; i < pnum && prime[i] <= sqr; i++)
    {
        if(n % prime[i] == 0)
        {
            fac[fnum].f = prime[i];
            fac[fnum].cnt = 1;
            n /= prime[i];
            while(n % prime[i] == 0)
            {
                fac[fnum].cnt++;
                n /= prime[i];
            }
            fnum++;
            if(n == 1)
                break;
        }
    }
    if(n != 1)
    {   //存在大于sqrt(n)的素因数
        fac[fnum].f = n;
        fac[fnum++].cnt = 1;
    }
    for(int i = 0; i < fnum; i++)
    {
        if(i != 0)
            printf("*");
        printf("%d", fac[i].f);
        if(fac[i].cnt > 1)
            printf("^%d", fac[i].cnt);
    }
    printf("\n");
    return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值