C++数论基础+字符串模拟基础练习题--分解质因数

题目描述:

题面


正整数分解为质因式,输出如下形式:如

2 = 2, 3 = 3, 4 = 2^2, 6 = 2 \times 3, 100 = 2^2\times5^2


输入


输入一行,包含一个正整数n

输出


输出n的质因式表达

样例


输入:2

输出:2=2

输入:10

输出:10=2*5

输入:100

输出:100=2^2*5^2

数据范围


1\leq n\leq 10^8

题目分析

我们看到数据范围就不经有点害怕,如果写一个判断质数的函数并一个个枚举过去,最坏情况下时间复杂度为O(\sqrt{n}*n),显然不可取。(1 0000 0000之内最大的质数是9999 9989,大家可以去试试电脑性能)所以我们需要一种比较快的筛法,欧拉筛和埃式筛都是可以的,网上犇犇那么多,我在这里也不讲了。

但是我们只要认(一)真(通)分(乱)析(猜)就会发现,越大的数越可能是合数,如果是合数,大概率是可以被较小的组合分解的。再根据基础数论,稍微优化一下:除了2以外,2的倍数都是合数,所以可以将i每次加2,时间复杂度就被我们减少到了O(\sqrt{n}\times\frac{n}{2})。提交试一试就发现,甚至不需要加上优化就能AC,出题人也挺仁慈的,没有放个特别大的质数来卡我们。

题解

这是一道非常水的入门基础数论+字符串模拟题,话不多说,边放代码边讲

//
//  main.cpp
//  D. 数论基础2-分解质因数
//
//  Created by SkyWave Sun on 2022/9/2.
//

#include <iostream>
using namespace std;
bool isPrime(int num) {//判断质数,本题数据范围较小,不需要用筛法
    if (num <= 1) {//防止悲剧
        return false;
    }
    for (int i = 2; i*i<=num; ++i) {//一个合数必定有小于等于自己的一个质因数
        if (num % i == 0) {
            return false;
        }
    }
    return true;
}
int main(int argc, const char * argv[]) {
    int n;
    scanf("%d",&n);
    printf("%d=",n);
    bool flag = false;
    if (n == 0 || n == 1) {
        printf("%d",n);//防止悲剧
    }
    for (int i = 2; i<=n; ++i) {//可以将2特判一下,然后i每次+=2,减少时间复杂度
        int up = 0;//指数
        if (isPrime(i)) {
            while (n % i == 0) {//将每个质因子i枚举到没有为止
                n /= i;
                ++up;//如果还包含质因子i指数就增加1
            }
        }
        if (up == 0) {
            continue;
        }
        if (!flag) {//骚操作,是为了不输出多余的*
            flag = true;
        }else {
            putchar('*');
        }
        if (up == 1) {
            printf("%d",i);
        }else {
            printf("%d^%d",i,up);
        }
        if (n == 0) {//减少时间复杂度
            break;
        }
    }
    putchar('\n');
    return 0;
}

完结撒花!

看不懂的请在评论区留言~

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值