[NOIP2012 普及组] 质因数分解
Dreamlands · · 个人记录
第一次摸到这道题还想了有一会儿,又是质因数相乘的积,又是较大,
突然反应过来这是最小质因数,
做完看了一圈题解,发现好像没几个注意到一个很重要的细节
仔细看题,你会发现对于这个正整数n它一定是两个质数相乘,
换而言之,如果你找到了n除1和本身外的任意因数,那么它一定是质数,
也就是说,对于你从2开始找到的第一个质数,n/它就是我们要的答案,并且这个数一定是质数,也就是答案一定正确
这太简单了,那么我们不妨对这个题目进行一个思路拓展,
对于一个正整数n,假设它由多个质数相乘构成
其实仔细想想思路还是很简单,对于任意的n,假设你去分解它,把它变成除1和本身的所有因数相乘的积,
那么对于最小的因数a,它一定是质数,否则它一定会被分成更小的质因数相乘的结果,
也就是说,从2开始去寻找可以整除n的数a,对于可能存在的,它的倍数构成的合数,在一定会在当前这步被分解掉,
也就说,对于这个因数a的倍数合数,一定会在当前这步被预处理解决,
那么这样就可以得到n的最小质因数a,当然这样得到的n/a一定不是质数,
所以我在代码里写的朴素根号n判断其实多此一举,check并不需要
这段补充拓展只是一个思路的提供,原理叫什么我忘记了
那么回到这道题,最小质因数代码成立吗?
当然成立,因为对于任意的n,它应该只有4个因数,1,最小质因数a,n/a,n四个数
显而易见,这样由方案2搜索出来的a和方案1搜索出来的a是完全一致的
因为二者寻找到的第一个a一定是最小质因数,否则它会被分解成两个更小的a
到这里,你会发现方案1和2的本质是一样的,都是从小开始搜索,保证找到的第一个因数一定不会被分解,
差别在于方案1仅针对这道题的情况进行了分析,而方案2则是对方案1思路的总结和拓展上升。
也就是说,去掉题目条件限制,方案2的搜索方式依然可以证明成立,
思路讲完了,代码在下面
AC代码(一):
#include<iostream>
using namespace std;
int n,rec=-1,n1;
bool check(int a) {
for(register int i=2; i*i<=n; i++) {
if(a%i==0) {
return false;
}
}
return true;
}
int main() {
scanf("%d",&n);
n1=n;
for(register int i=2; i*i<=n; i++) {
if(n%i==0) {
printf("%d",n1/i);
return 0;
}
}
cout<<"Wrong!";
return 0;
}
AC代码(二):
#include<iostream>
using namespace std;
int n,rec=-1,n1;
bool check(int a) {
for(register int i=2; i*i<=n; i++) {
if(a%i==0) {
return false;
}
}
return true;
}
int main() {
scanf("%d",&n);
n1=n;
for(register int i=2; i*i<=n; i++) {
if(n%i==0) {
check:
n/=i;
if(n%i==0){
goto check;
}
if(check(n1/i)==true) {
printf("%d",n1/i);
return 0;
}
}
}
cout<<"Wrong!";
return 0;
}