题解:AcWing 867 分解质因数

【题目来源】

AcWing:867 分解质因数 - AcWing题库

【题目描述】

给定 \(n\) 个正整数 \(a_i\),将每个数分解质因数,并按照质因数从小到大的顺序输出每个质因数的底数和指数。

【输入】

第一行包含整数 \(n\)

接下来 \(n\) 行,每行包含一个正整数 \(a_i\)

【输出】

对于每个正整数 \(a_i\),按照从小到大的顺序输出其分解质因数后,每个质因数的底数和指数,每个底数和指数占一行。

每个正整数的质因数全部输出完毕后,输出一个空行。

【输入样例】

2
6
8

【输出样例】

2 1
3 1

2 3

【核心思想】

  1. 问题分析:给定 \(n\) 个正整数 \(a_i\),需要将每个数分解为质因数的乘积形式 \(a_i = p_1^{\alpha_1} p_2^{\alpha_2} \cdots p_k^{\alpha_k}\),并按质因数从小到大的顺序输出每个质因数的底数 \(p_j\) 和指数 \(\alpha_j\)

  2. 算法选择

    • 试除法分解质因数(Trial Division):对于待分解整数 \(x\),从 \(2\) 开始枚举到 \(\sqrt{x}\),若 \(i\) 能整除 \(x\),则 \(i\) 是一个质因数,通过循环除尽所有 \(i\) 因子并统计指数
    • 剩余质数处理:若除尽所有 \(\leq \sqrt{x}\) 的因子后 \(x > 1\),则剩余的 \(x\) 本身就是一个质因数,且指数一定为 \(1\)
  3. 关键步骤

    • 读取输入\(n\)\(n\) 个正整数 \(a_i\)
    • 分解函数 divide(x)
      • 枚举 \(i\)\(2\)\(\lfloor\sqrt{x}\rfloor\)(代码中用 i \leq x / i
      • \(x \bmod i = 0\),初始化指数计数器 \(s = 0\)
      • while (x \% i == 0):不断执行 x /= i; s++;,直到 \(x\) 不能被 \(i\) 整除
      • 输出质因数 \(i\) 及其指数 \(s\)
      • 枚举结束后,若 \(x > 1\),输出 x 1
      • 输出一个空行作为每组结果的结束
    • 逐数处理:对每个 \(a_i\) 调用 divide(a_i)
  4. 时间/空间复杂度

    • 时间复杂度:\(O(n\sqrt{a_i})\),对每个数最多进行 \(\sqrt{a_i}\) 次试除
    • 空间复杂度:\(O(1)\),仅使用常数额外空间
  5. 试除法分解质因数的核心思想

    • 合数过滤性质:若 \(i\) 是合数,则 \(i\) 的质因数必定已在之前被除尽,因此 \(x\) 不可能再被 \(i\) 整除,无需预处理质数表即可保证枚举到的因子都是质数
    • 除尽策略:每次找到一个质因数后,用 while 循环将其全部除尽,确保每个质因数只被记录一次,输出结果天然按升序排列
    • 根号边界:只需枚举到 \(\sqrt{x}\),剩余大于 \(1\) 的部分必为单一质因数
    • 适用于单个或少量整数的质因数分解;对于大规模区间分解,应结合线性筛预处理质数表以加速

【解题思路】

【算法标签】

约数

【代码详解】

#include <bits/stdc++.h>
using namespace std;

int n;  // 定义变量n,表示输入的数的个数

// 分解质因数的函数
void divide(int x) {
    // 从2开始枚举可能的质因数
    for (int i = 2; i <= x / i; i++) {
        if (x % i == 0) {  // 如果i是x的质因数
            int s = 0;     // s记录质因数i的幂次
            while (x % i == 0) {  // 将x中的所有i因子除掉
                x = x / i;
                s++;
            }
            cout << i << " " << s << endl;  // 输出质因数i及其幂次
        }
    }

    // 如果x大于1,说明x本身是一个质数
    if (x > 1) {
        cout << x << " " << 1 << endl;  // 输出x及其幂次1
    }

    cout << endl;  // 每组分解结果后输出一个空行
}

int main() {
    cin >> n;  // 输入数的个数n

    // 循环处理每个数
    while (n--) {
        int x;
        cin >> x;  // 输入待分解的数x
        divide(x); // 调用divide函数分解x的质因数
    }

    return 0;
}
#include <bits/stdc++.h>
using namespace std;

int n;  // 数字的个数

// 质因数分解函数
// 参数:n - 要分解的数字
void divide(int n)
{
    // 从最小的质数2开始尝试
    for (int i = 2; i <= n / i; i++)  // 优化:只检查到√n
    {
        // 如果i是n的质因数
        if (n % i == 0)
        {
            int s = 0;  // 计数器,记录质因数i的指数

            // 不断除以i,直到n不能被i整除
            while (n % i == 0)
            {
                n /= i;  // 除以质因数i
                s++;     // 指数加1
            }

            // 输出质因数i及其指数s
            cout << i << " " << s << endl;
        }
    }

    // 处理最后一个质因数(如果n>1,那么n本身就是一个质因数)
    if (n > 1)
    {
        cout << n << " " << 1 << endl;
    }

    // 每个数字分解完后输出空行
    cout << endl;
}

int main()
{
    cin >> n;  // 输入要分解的数字个数

    for (int i = 1; i <= n; i++)
    {
        int x;
        cin >> x;     // 输入要分解的数字
        divide(x);    // 调用质因数分解函数
    }

    return 0;
}

【运行结果】

2
6
2 1
3 1

8
2 3
posted @ 2026-06-21 11:23  团爸讲算法  阅读(14)  评论(0)    收藏  举报