PAT乙级(Basic Level)练习题 分解因数

题目描述
所谓因子分解,就是把给定的正整数a,分解成若干个素数的乘积,即 a = a1 × a2 × a3 × … × an,并且 1 < a1 ≤ a2 ≤ a3 ≤ … ≤ an。其中a1、a2、…、an均为素数。
先给出一个整数a,请输出分解后的因子。

输入描述:
输入包含多组数据,每组数据包含一个正整数a(2≤a≤1000000)。

输出描述:
对应每组数据,以“a = a1 * a2 * a3…”的形式输出因式分解后的结果。

输入例子:

10
18

输出例子:

10 = 2 * 5
18 = 2 * 3 * 3

\color{blue}解题思路:
这一题我一开始的思路是先搞一个表存储1-1000000的素数,然后从小到大进行穷举因数,应该也有不少道友也会这样想。
但是这里有一个潜在的数学规律,假设a合数,并且a == b * c,其中bc中必定有一个 ≤ sqrt(a),不可能出现bc同时大于a
因此我们搜索的范围缩小为[2, sqrt(a)]

还有一点,当我们把a的所有2因数都分解出来后,2的倍数(4、6、8...)都不可能再分解出来,比如100分解出2 x 2后,无法再分出2的倍数,同样分解出所有3因数后,则无法再分出3的倍数…

总结一下就是,在[2, sqrt(a)]区间从小到大逐渐试探的时候,碰到一个分解的因数时a,就一直分解a,直到不能再分解a,此时也不可能再分解出a的倍数。
假设a是素数,则a的倍数(必定是合数)都被排除了试探,但是你如何保证a就一定不是合数呢?也就是我们会担心分解出一个合数a怎么办。

再回到我们得试探方法------ [ 2 , s q r t ( a ) ] \color{red}在`[2, sqrt(a)]`区间从小到大逐渐试探

首先试探了2(素数),2的倍数被排除了,之后试探2的倍数绝对不会成功
接着试探了3(素数),3的倍数被排除了,之后试探3的倍数绝对不会成功
(不成功)试探42的倍数),如果此时还能整除4,那就能试探2了,自相矛盾。。。
试探了5(素数),5的本书被排除了,之后试探5的倍数绝对不会成功
....
依次类推,当我们在试探较小的素数时,已经排除了对应的倍数,
最终导致我们试探出的都是素数!!!

\color{red}如果你实在想不通,请手动在纸上模拟`筛选法`找素数的过程!

有一种找素数的方法称为筛选法,比如让你找[1,100]之间的素数。
你只要在[2,100]区间从小到大开始,拿到一个素数,就筛掉它的所有倍数。
比如拿了2(素数),筛选掉2的所有倍数,然后拿3(素数),筛选掉3的所有倍数,以此类推,最后你拿出的就是[1,100]之间的所有素数。

\color{blue}代码实现:

#include <iostream>
#include <math.h>
using namespace std;

int main(int argc, const char * argv[]) {
    int number = 0;
    //scanf返回值为正确输入数据的变量个数,当一个变量都没有成功获取数据时,此时返回-1
    while (scanf("%d", &number) != - 1) {
        printf("%d = ", number);
        //只需要从[2, sqrt(number)]试探即可
        int maxEle = sqrt(number);
        for (int i = 2; i <= maxEle; ++i) {
        	//如果能分解出i,则一直分解出i,直到不能再分解,这样可以避免分解出i的倍数(i的倍数一定是合数)
            while (number % i == 0) {
                if (i == number) {
                	//最后一个数之后不能输出*了,需要单独输出
                	//注意输出格式: 10 = 2 * 5
                    break;
                }
                printf("%d * ", i);
                number /= i;
            }
        }
        printf("%d\n", number);
    }
    return 0;
}

在这里插入图片描述

发布了1005 篇原创文章 · 获赞 269 · 访问量 22万+

猜你喜欢

转载自blog.csdn.net/qq_41855420/article/details/104654670
今日推荐