1. N的因子个数
条件:给定任意一个一个正整数N
要求:求其因子的个数
首先给出结论:对于任意的整型N,分解质因数得到N= P1^x1 * P2^x2* …… * Pn^xn;
则N的因子个数M为 M=(x1+1) * (x2+1) * …… *(xn+1);
证明过程:
首先 举个例子吧
24 = 2^3 * 3^1;
其质因子有:为2和3 指数为 3和1
那么对于2 有0 1 2 3四种指数选择,对于3 有0 1两种指数选择
所以 就是4 * 2 = 8 个因子个数
如果还是不懂,那么我们就列举出来吧
2 3
2^0*3^0=1 2^0*3^1=3
2^1*3^0=2 2^1*3^1=6
2^2*3^0=4 2^2*3^1=12
2^3*3^0=8 2^3*3^1=24
结果很清晰了吧??其实这里用到了数学的排列组合的知识
也就是说每一个质因子的不同指数幂与其它质因子相乘,得到的结果一定不会重复
因此能够将所有的因子都列举出来。
所以N的因子数M,我们可以用M=(x1+1) * (x2+1) * …… *(xn+1)表示
代码:
/*
*
* N的因子个数
*/
#include<iostream>
using namespace std;
int main()
{
int N, count = 1, dis = 2, ans = 1;
cin >> N; //Input thenumber of N
while( N != 1 )
{
while( N % dis == 0 ) //"dis" into the circle must be a prime
{
N /= dis;
count++;
}
ans *= count;
count = 1;
dis++;
}
cout<< ans <<endl;
return 0;
}
2. N!的因子个数
有上面的结论,这个问题就变得明朗多了吧?嘿嘿,不要着急,这里面还有许多细节问题需要我们考虑。
a. 最大的质因子一定不会大于N
b. N的质因子并不完全包含N!所有的质因子
至于原因是什么,自己想想吧,嘿嘿
那我们就直接说思路了:
首先,我们可以把所有的N以内的质数给打表求出来
然后,求每一个质因子的指数个数,这里用到了一个公式,:
ei = [N/pi^1] + [N/pi^2] + …… + [N/pi^n] 其中[]为取整
附:这一步最近又想到了一个更好的方法
int ei=0;
while(N)
ei+=(N/=pi);
怎么样??
(想一想为什么,实在想不通你就举个例子试一下)
最后,就是套公式计算了,M=(e1+1)*(e2+1)*……*(en+1)
还是举个例子吧
比如5!
质因子2的指数是 2+1=3;
质因子3的指数是 1;
质因子5的指数是 1;
所以因子个数为 4 * 2 * 2= 16
5!=120 因子有1 2 3 4 5 6 810 12 15 20 24 30 40 60 120 刚好16个
代码:
/*
* N!的因子个数
*/
#include<iostream>
using namespace std;
int prime[1005], num = 0;// "num"is the prime
bool m[10005] = { 1, 1, 0};
void SetTable(int x) // sieve
{
for( int i = 2; i <= x; i++ )
if(!m[i])
{
prime[num++] = i;
for( int j = i+i ; j <= x; j += i)
m[j] = true;
}
}
int GetEi(int n ,int x)
{
int ans = 0;
while(n)
ans += (n/=x);
return ans+1;
}
int main()
{
int N, ans = 1;
cin >> N; //Input thenumber of N
SetTable(N);
for(int i = 0; i < num; i++ )
ans *= GetEi(N, prime[i]);
cout<< ans <<endl;
return 0;
}
3.给定数列的乘积因子个数
其实这个也是基于第一个结论得到的。
给定 a1 a2 a3 …… an;
我们可以找到最大的一个元素Max(a);
把Max以内的素数打表
然后把质因子清零,进行如下循环,就可以找到各个质因子的个数:
for(a=1;a<=n;a++)
for(p=1;p<_;p++ )
if(__)
e(p)++;
这样质因子的质数个数就求出来了,然后就可以根据公式M=(e1+1)*(e2+1)*……*(en+1)求出因子个数
代码:
/*
* 给定数列乘积的因子个数
*/
#include<cstdio>
#include<iostream>
using namespace std;
int prime[1005], num = 0;// "num"is the prime
bool m[10005] = { 1, 1, 0};
void SetTable(int x) // sieve
{
for( int i = 2; i <= x; i++ )
if(!m[i])
{
prime[num++] = i;
for( int j = i+i ; j <= x; j += i)
m[j] = true;
}
}
int main()
{
int N, n[100], Max = -1;
cin >> N; //Input thenumber of N
for(int i = 1; i <= N; i++ ){
cin >> n[i];
if( n[i] > Max )
Max = n[i];
}
SetTable(Max);
int ans = 0;
for( int i = 0; i < num; i++ )
for( int j = 1; j <= N; j++ )
while( n[j]%prime[i] == 0 )
{
ans ++;
n[j] /= prime[i];
}
cout<< ans <<endl;
return 0;
}