1059 Prime Factors (25 分| 质因子分解,附详细注释,逻辑分析)

写在前面

  • 实现思路
    • 素数/质数判断函数
    • 循环生成素数码表
    • 质因子结构体
      • 循环遍历迭代记录并更新质因子、质因子幂指数
      • 质因子特殊处理,无法被根号n内的质因子除尽
    • 格式化打印输出
      • 质因子递增序
      • 指数大于1,输出幂指数
      • prime : 质数
  • 问题点
    • 素数表大小 10^5
    • n==1,特判
  • 核心问题: 方案实现,细节处理
    • 题目有一定难度,细节处理耗费时间
    • 45分钟

测试用例

input:
97532468
output:
97532468=2^2*11*17*101*1291

input:
1
output:
1=1

input:
7
output:
7=7

input:
8
output:
2^3

input:
2147483647
output:
2147483647=2147483647

input:
2147483646
output:
2147483646=2*3^2*7*11*31*151*331

ac代码

  • 推荐,易理解,有一定代码量
#include 
#include 
using namespace std;

const int maxn = 100010;
// 判断n是否为素数
bool is_prime(int n)
{
    if(n==1) return false;
    for(int i=2; i*i <= n; i++)
        if(n%i == 0)
            return false;
    return true;
}

int prime[maxn], pNum = 0;
// 计算素数表
void find_prime()
{
    for(int i=1; i<maxn; i++)
        if(is_prime(i) == true)
            prime[pNum++] = i;
}

struct factor
{
    int x, cnt;  // x为质因子, cnt为其个数
} fac[10];

int main()
{
    find_prime();
    int n, num = 0;
    scanf("%d", &n);
    if(n==1) printf("1=1");  // 特判1的情况
    else
    {
        printf("%d=", n);
        int sqr = sqrt(n);

        // 枚举根号n以内的质因子
        for(int i=0; i<pNum && prime[i] <= sqr; i++)
        {
            // prime[i]是n的因子
            if(n%prime[i] == 0)
            {
                // 记录该因子
                fac[num].x = prime[i];
                fac[num].cnt = 0;
                // 计算出质因子prime[i]的个数
                while(n % prime[i] == 0)
                {
                    fac[num].cnt++;
                    n /= prime[i];
                }
                num++;  // 不同质因子个数加1
            }
            // 及时退出循环,节省时间
            if(n==1) break;
        }
        // 未被根号n内的质因子除尽,则一定有1个大于n的质因子
        if(n != 1)
        {
            fac[num].x = n;
            fac[num++].cnt = 1;
        }

        // 格式化输出计算结果
        for(int i=0; i<num; i++)
        {
            if(i>0) printf("*");
            printf("%d", fac[i].x);
            if(fac[i].cnt > 1)
                printf("^%d", fac[i].cnt);
        }
    }
    return 0;
}

学习代码

  • 实现思路
    • 循环,非质数下标置为0。剩余为1下标均为质数
    • 双层循环,计算质因数、质数并合法打印输出
#include 
#include 
using namespace std;
vector<int> prime(500000, 1);
int main() {
    for(int i = 2; i * i < 500000; i++)
        for(int j = 2; j * i < 500000; j++)
            prime[j * i] = 0;
    long int a;
    scanf("%ld", &a);
    printf("%ld=", a);
    if(a == 1) printf("1");
    bool state = false;
    for(int i = 2; a >= 2;i++) {
        int cnt = 0, flag = 0;
        while(prime[i] == 1 && a % i == 0) {
            cnt++;
            a = a / i;
            flag = 1;
        }
        if(flag) {
            if(state) printf("*");
            printf("%d", i);
            state = true;
        }
        if(cnt >= 2)
            printf("^%d", cnt);
    }
    return 0;
}

你可能感兴趣的:(PAT(甲级),算法比赛相关)