题目:http://acm.nyist.net/JudgeOnline/problem.php?pid=56
(一)描述:
给定两个数m,n,其中m是一个素数。
将n(0<=n<=10000)的阶乘分解质因数,求其中有多少个m。
题目:http://acm.nyist.net/JudgeOnline/problem.php?pid=70
(二)描述:
给定两个数n,m,其中m是一个素数。将n(0<=n<=2^31)的阶乘分解质因数,求其中有多少个m。
注:^为求幂符号。
题目一较简单,直接暴力就可以过,但是题目二的范围较大,暴力无法过,下面说说二怎么过。
这里实际上是有一个公式的(设f(n)表示n里面有多少个m)
下面给出证明过程:
设g(n)表示n的阶乘,那么g(n) = 1 * 2 * 3 * 4 * ... * n。
那么当n < m时,一定无法分解出m,所以f(n)为0。
当n = m时,只能分解出一个m,所以f(n)为1。
当n > m时,对g(n)进行变形。
g(n) = m * 2m * 3m * ... * km * r (k = n/m取整,r为不是m的倍数的数的乘积)
= 1 * 2 * 3 * ... * k * m * m * m * ... * m(一共k个m) * r
= g(k) * m^k * r
到这里可以明显的看出来,m^k有k个m,接下来求g(k)里有多少个m即可,求解的方法重复上面的过程即可。。
所以 f(n) = k + f(k) (k = n/m取整)
综上:
#include <stdio.h>
int contain(int n, int m)//n的阶乘分解质因数包含几个m
{
if(n < m)
return 0;
else if(n == m)
return 1;
else
return n/m + contain(n/m, m);
}
int main()
{
int t, m, n;
scanf("%d", &t);
while(t--)
{
scanf("%d%d", &n, &m);
printf("%d\n", contain(n,m));
}
return 0;
}