题解:学而思编程 完全平方数
【题目来源】
学而思编程:完全平方数
【题目描述】
完全平方指用一个整数乘以自己,例如 \(1*1\),\(2∗2\),\(3*3\) 等,依此类推。若一个数能表示成某个整数的平方的形式,则称这个数为完全平方数。
现在给定你一个正整数 \(n\),请你找到一个最小的正整数 \(x\),使得 \(x*n\) 是一个完全平方数。
【输入】
一行,包含一个正整数 \(n\)。
【输出】
一行,包含一个正整数 \(x\),表示结果。
【输入样例】
12
【输出样例】
3
【核心思想】
-
问题分析:给定正整数 \(n\),求最小的正整数 \(x\),使得 \(n \times x\) 是完全平方数。这是一个质因数分解 + 奇偶补全问题,关键在于理解完全平方数的质因数分解中每个质因子的指数均为偶数。
-
算法选择:
- 质因数分解:将 \(n\) 分解为质因数的幂次乘积
- 奇数指数补全:对于每个指数为奇数的质因子,\(x\) 需要乘上该质因子一次使其变为偶数
-
关键步骤:
- 初始化:读取 \(n\),
res = 1 - 质因数分解(遍历 \(i\) 从 \(2\) 到 \(\sqrt{n}\)):
- 若 \(n \bmod i = 0\):
exponent = 0- 当 \(n \bmod i = 0\) 时循环:
exponent++n /= i
- 若
exponent % 2 == 1:res *= i(指数为奇数,需补一次)
- 若 \(n \bmod i = 0\):
- 处理剩余质因子:
- 若
n > 1:res *= n(剩余的 \(n\) 是一个大于 \(\sqrt{原n}\) 的质因子,指数为 \(1\),需补一次)
- 若
- 输出
res
- 初始化:读取 \(n\),
-
时间/空间复杂度:
- 时间复杂度:\(O(\sqrt{n})\),质因数分解
- 空间复杂度:\(O(1)\),仅需常数变量
-
质因数分解的核心思想:
- 完全平方数的性质:完全平方数的质因数分解中,每个质因子的指数都是偶数
- 最小补全策略:\(n \times x\) 要成为完全平方数,\(x\) 只需提供 \(n\) 中指数为奇数的那些质因子各一次,使总指数变为偶数
- 无需存储所有因子:边分解边判断指数的奇偶性,奇数立即乘入
res,无需保存完整分解式 - 剩余处理:循环结束后若 \(n > 1\),说明剩余的是一个质因子(指数为 \(1\),奇数),必须乘入
res - 适用于"完全平方数判定/构造"类问题,质因数分解是揭示数论结构的根本方法
【解题思路】

【算法标签】
约数
【代码详解】
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
int main() {
LL n;
cin >> n; // 输入正整数n
LL res = 1; // 初始化结果为1
// 遍历所有可能的质因数,从2开始
for (LL i = 2; i * i <= n; i++) {
if (n % i == 0) { // 如果i是n的因数
int exponent = 0; // 记录当前质因数的指数
// 分解质因数,计算指数
while (n % i == 0) {
exponent++;
n /= i;
}
// 如果指数是奇数,乘以该质因数一次
if (exponent % 2 == 1) {
res *= i;
}
}
}
// 处理剩余的质因数(大于sqrt(n)的情况)
if (n > 1) {
res *= n;
}
cout << res << endl; // 输出结果
return 0;
}
【运行结果】
12
3
浙公网安备 33010602011771号