题目描述:
求正整数N(N>1)的质因数的个数。 相同的质因数需要重复计算。如120=22235,共有5个质因数。
输入描述:
可能有多组测试数据,每组测试数据的输入是一个正整数N,(1<N<10^9)。
输出描述:
对于每组数据,输出N的质因数的个数。
样例输入:
120
样例输出:
5
解题思路: 输入值的取值规模是
1
0
9
10^9
109, 筛得的素数数目只需
1
0
5
10^5
105,这样处理的理论依据是:n至多有一个大于sqrt(n)的素因数(否则两个大于sqrt(n)的数相乘大于n)。且若1~10000内的素数都不是某输入值的素因数,那么该数的质因数一定等于其本身,且幂指数为1。
代码流程:
1.利用素数筛法得0到100000内的所有素数
2.输入n
3.依次测试步骤1中得到的素数能否整除n,若能则表明该素数为它的一个素因数。
4.不断将n除以该素数,直到不能再被整除为止,同时统计其幂指数。
5.若在完成某个素数的幂指数统计后,n为1,则表明n的所有素因数全部被分解出来。
6.若遍历、测试、分解完所有的预处理出来的素数,n仍然没有被除成1,则表明n存在一个大于100000的因子,且该因子必为其素因数,且其幂指数必为1。
7.最后,将所有素因数的幂指数相加,即得到素因数的个数。
#include<bits/stdc++.h>
using namespace std;
bool mark[100001];//mark[x]为true,则表示该数x已被标记为非素数
int prime[100000];//保存筛得的素数
int primeSize;//保存已得到的素数个数
void init(){//素数筛法
for(int i=0; i<=100000; i++)
mark[i] = false;//初始化,所有数字均标记为素数
primeSize = 0;//得到的素数个数初始为0
for(int i=2; i<=100000; i++){//依次遍历2到10000所有数字
if(mark[i]==true) continue;//若该数字已经被标记为非素数,则跳过
prime[primeSize++] = i;//否则,记录该素数
if(i>=1000) continue;//大于1000的不需要再进行标记,因为i在1000以内已经将100000以内的非素数都标记完了
for(int j=i*i; j<=1000; j+=i){//将该素数的所有倍数标记为
mark[j] = true;
}
}
}
int main(){
init();
int n;
while(scanf("%d", &n)!=EOF){
int ansPrime[50]; //按顺序保存分解出的素因数
int ansSize = 0; //分解出素因数的个数
int ansNum[30]; //保存分解出的素因数对应的幂指数
for(int i=0; i<primeSize; i++){//依次测试每一个素数
if(n%prime[i]==0){//若该素数能整除被分解的数
ansPrime[ansSize] = prime[i];//则该素数为其素因数
ansNum[ansSize] = 0; //初始化幂指数为0
while(n%prime[i]==0){
ansNum[ansSize]++;
n /= prime[i];
}
ansSize++; //素因数数量增加
if(n==1) break; //若已被分解成1,则分解终止
}
}
if(n!=1){//若测试完2到100000内所有的素因数,n仍然没有被分解为1,则剩余的因数一定是一个大于100000的素因数
ansPrime[ansSize] = n; //记录该数
ansNum[ansSize++] = 1;//其幂指数只能为1
}
int ans = 0;
for(int i=0; i<ansSize; i++)
ans += ansNum[i]; //统计各个素因数的幂指数
cout << ans << endl;//输出
}
return 0;
}