牛客网刷题:质数因子
质数也叫素数,素数是指在大于1的自然数中,除了1和它本身以外,不能被其他自然数整除的数。
话不多说,直接开始题目:
描述
功能:输入一个正整数,按照从小到大的顺序输出它的所有质因子(重复的也要列举)(如180的质因子为2 2 3 3 5 )
数据范围: 1≤n≤2×10^9+14
输入描述:
输入一个整数
输出描述:
按照从小到大的顺序输出它的所有质数的因子,以空格隔开。
示例1
输入:
180
复制输出:
2 2 3 3 5
1、最先想到的暴力算法了
#include <iostream>
#include <math.h>
using namespace std;
int main()
{
int num;
while(cin >> num)
{
size_t i = 2;
for(; i < num;)
{
if(num % i == 0)
{
cout<<i<<" ";
num = num / i;
}
else
{
i++;
}
}
if(num >=2)
{
cout<<num<<endl;
}
}
return 0;
}
运行超时了。。。脸一黑看来不是这么简单for循环就行的,想了下应该是当num值很大的时候这个循环次数也就太大了。
2、缩小运算范围
#include <iostream>
#include <math.h>
using namespace std;
int main()
{
int num;
while(cin >> num)
{
size_t i = 2;
for(; i <= num/2;)
{
if(num % i == 0)
{
cout<<i<<" ";
num = num / i;
}
else
{
i++;
}
}
if(num >= 2)
{
cout<<num<<endl;
}
}
return 0;
}
想着素数除了1和他本身外不能整除其他数,那么最小可能因子就是2了,于是缩小1/2的范围了,运行还是超时了,脸又黑。。。
3、再次缩小运算范围
#include <iostream>
#include <math.h>
using namespace std;
int main()
{
int num;
while(cin >> num)
{
size_t i = 2;
for(; i <= sqrt(num);)
{
if(num % i == 0)
{
cout<<i<<" ";
num = num / i;
}
else
{
i++;
}
}
if(num >= 2)
{
cout<<num<<endl;
}
}
return 0;
}
任何一个数只要有质数因子,那么可以假设变化成x*y,因为我们是i++方式递增去判断整除的,那么我们一定是先计算了小的素数再计算的大的素数。这里我们假设x与y中总有一个较小数(或者x与y相等),那么这个较小数肯定不大于sqrt(num),因为要是较小数超过了sqrt(num),那它就变成了较大数了。例如49,较小数也就是sqrt(49)=7是不会超过7的,如果较小的数都超过了7,较大数比7大,那乘积不就超过49了么。