[NOIP 2012 普及组] 质因数分解 的题解
记住只在没有思路时使用题解,不要从它复制粘贴代码。请尊重题目和题解的作者。
在解题之前提交题解的代码会导致封禁。
在解题之前提交题解的代码会导致封禁。
作者:
概述
本题要求出正整数 的两个不同质因数中较大的那个。关键在于从小到大递增试除:第一个能整除
的数必然是较小的质因数,用
除以它即得答案。
分析
核心观察
的正因数只有
、
、
、
这四个(其中
均为质数)。因此从
开始递增试除,第一个整除
的数一定是
,它本身必为质数,无需额外的质数判定。
思路
设 ,其中
均为质数。由
可得
即 ,较小质数必定落在
以内。
于是从小到大枚举 ,第一个满足
的
就是
,输出
即可。枚举过程中不会先遇到合数因子——
的因数集只有
,这保证了第一个被找到的因子必为质数。
若把枚举上界放松到 ,复杂度会退化为
,在
时无法接受;把上界收紧到
是解法的全部要点。另有先筛出
以内全部质数再试除的做法,复杂度同为
,但需要额外数组,本题直接试除即可。
具体示例
以 为例:枚举
时
,不整除;枚举
时
,整除,故较小质数为
,答案为
。
再看 :该数分解为
,两因子均为质数,且
,因此循环需从
一直枚举到
,共试除
次,是本题数据中最坏的一组。可见上界
与实际的首次命中位置相当接近。
算法步骤
- 读入整数存入
n,令i的初值为。
- 若
i的平方大于n,结束循环(题面保证输入合法,实际不会走到这一步)。 - 若
i整除n,输出n除以i的商并结束程序。 - 令
i增加,回到第
步。
复杂度分析
- 时间:
。最坏情况试除次数不超过
次。
- 空间:
。
实现注意事项
- 循环条件写成
,不要用开方结果作比较,可完全避免浮点误差。
- 当
取到
时,中间量
最大约
,虽未超出
位有符号整数上限,但余量很小;用
位整数保存
更为稳妥。
- 只需输出较大质数,即
,不要输出枚举到的
本身。
- 找到整除的数后应立即输出并退出,无需继续枚举。
- 题面保证
是两个不同质数的乘积,最小值
对应
,不需要特判。
- Python 中取商须使用整除运算符,写成单斜杠会得到浮点数并可能引入精度误差。
源代码
#include <iostream>
using namespace std;
int main() {
long long n;
cin >> n;
for (long long i = 2; i * i <= n; ++i) {
if (n % i == 0) {
cout << n / i << endl;
return 0;
}
}
return 0;
}
n = int(input())
i = 2
while i * i <= n:
if n % i == 0:
print(n // i)
break
i += 1
评论