题目描述:
题面
正整数分解为质因式,输出如下形式:如
输入
输入一行,包含一个正整数
输出
输出的质因式表达
样例
输入:2
输出:2=2
输入:10
输出:10=2*5
输入:100
输出:100=2^2*5^2
数据范围
题目分析
我们看到数据范围就不经有点害怕,如果写一个判断质数的函数并一个个枚举过去,最坏情况下时间复杂度为,显然不可取。(1 0000 0000之内最大的质数是9999 9989,大家可以去试试电脑性能)所以我们需要一种比较快的筛法,欧拉筛和埃式筛都是可以的,网上犇犇那么多,我在这里也不讲了。
但是我们只要认(一)真(通)分(乱)析(猜)就会发现,越大的数越可能是合数,如果是合数,大概率是可以被较小的组合分解的。再根据基础数论,稍微优化一下:除了2以外,2的倍数都是合数,所以可以将i每次加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;
}
完结撒花!
看不懂的请在评论区留言~