题解:AcWing 867 分解质因数
【题目来源】
AcWing:867 分解质因数 - AcWing题库
【题目描述】
给定 \(n\) 个正整数 \(a_i\),将每个数分解质因数,并按照质因数从小到大的顺序输出每个质因数的底数和指数。
【输入】
第一行包含整数 \(n\)。
接下来 \(n\) 行,每行包含一个正整数 \(a_i\)。
【输出】
对于每个正整数 \(a_i\),按照从小到大的顺序输出其分解质因数后,每个质因数的底数和指数,每个底数和指数占一行。
每个正整数的质因数全部输出完毕后,输出一个空行。
【输入样例】
2
6
8
【输出样例】
2 1
3 1
2 3
【核心思想】
-
问题分析:给定 \(n\) 个正整数 \(a_i\),需要将每个数分解为质因数的乘积形式 \(a_i = p_1^{\alpha_1} p_2^{\alpha_2} \cdots p_k^{\alpha_k}\),并按质因数从小到大的顺序输出每个质因数的底数 \(p_j\) 和指数 \(\alpha_j\)。
-
算法选择:
- 试除法分解质因数(Trial Division):对于待分解整数 \(x\),从 \(2\) 开始枚举到 \(\sqrt{x}\),若 \(i\) 能整除 \(x\),则 \(i\) 是一个质因数,通过循环除尽所有 \(i\) 因子并统计指数
- 剩余质数处理:若除尽所有 \(\leq \sqrt{x}\) 的因子后 \(x > 1\),则剩余的 \(x\) 本身就是一个质因数,且指数一定为 \(1\)
-
关键步骤:
- 读取输入:\(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 - 输出一个空行作为每组结果的结束
- 枚举 \(i\) 从 \(2\) 到 \(\lfloor\sqrt{x}\rfloor\)(代码中用
- 逐数处理:对每个 \(a_i\) 调用
divide(a_i)
-
时间/空间复杂度:
- 时间复杂度:\(O(n\sqrt{a_i})\),对每个数最多进行 \(\sqrt{a_i}\) 次试除
- 空间复杂度:\(O(1)\),仅使用常数额外空间
-
试除法分解质因数的核心思想:
- 合数过滤性质:若 \(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
浙公网安备 33010602011771号