【算法中的数学】分解质因数
分解质因数题解
题目传送门
867. 分解质因数 - AcWing题库
一、题目描述
给定 n 个正整数 aᵢ,将每个数分解质因数,并按照质因数从小到大的顺序输出每个质因数的底数和指数。每个正整数的质因数输出完毕后需要输出一个空行。
二、题目分析
这道题要求我们对给定的每个整数 aᵢ 进行质因数分解,并按照质因数从小到大的顺序输出每个质因数及其指数。例如:
- 6 可以分解为 2¹ × 3¹
- 8 可以分解为 2³
三、解题思路
- 对于每个数 a,从最小的质数 2 开始尝试除法
- 如果 i 能整除 a,就不断除以 i 并计数,直到不能整除为止
- 处理完所有可能的因数后,如果剩下的数大于 1,说明它本身就是一个质数
- 按照从小到大的顺序输出所有质因数及其指数
四、算法讲解
使用试除法进行质因数分解:
- 从 2 开始遍历到 √a,尝试每个可能的因数
- 当找到一个能整除 a 的因数 i 时,不断除以 i 并计数,记录这个因数的指数
- 由于我们从小到大遍历,所以能保证找到的因数都是质数(因为合数会被其质因数提前排除)
- 最后检查剩余的数,如果大于 1 则它本身也是质因数
以输入 8 为例:
- 2 能整除 8,计数 3 次(8 → 4 → 2 → 1),输出 2 3
- 最后剩余 1 不大于 1,结束
五、代码实现
#include <bits/stdc++.h>
using namespace std;
void solve()
{
int a;
cin >> a;
// 从最小的质数2开始尝试除法
for (int i = 2; i <= a / i; i ++)
{
if (a % i == 0) // 如果i是a的因数
{
int s = 0; // 记录指数
while (a % i == 0) // 不断除以i直到不能整除
{
a /= i;
s ++;
}
cout << i << " " << s << "\n"; // 输出质因数及其指数
}
}
// 处理剩余的大于1的数(它本身是质数)
if (a > 1)
cout << a << " " << 1 << "\n";
cout << "\n"; // 每个数处理完后输出空行
}
int main()
{
int t;
cin >> t;
while (t --)
solve();
return 0;
}
六、重点细节
- 循环条件
i <= a / i
:等价于 i ≤ √a,但避免了浮点数运算和溢出问题。 - 完全除尽每个质因数:保证后续处理的都是更大的质因数。
- 处理剩余的大质数:如果 a > 1,说明剩下的 a 本身是质数。
- 输出格式:每个质因数占一行,每个数处理完后要输出空行。
七、复杂度分析
- 时间复杂度:O(n√a),其中 n 是数字个数,a 是数字大小。对于每个数,最坏情况下需要遍历到 √a。
- 空间复杂度:O(1),只使用了常数个额外变量。
八、总结
这道题考察了质因数分解的基本方法,使用试除法可以高效解决。关键点在于:
- 从小到大尝试因数,保证找到的都是质数。
- 完全除尽每个质因数。
- 正确处理剩余的大质数情况。
- 注意输出格式要求。