题目链接:
原博链接【代码来自于这篇博客】:https://blog.youkuaiyun.com/m0_37036984/article/details/79024534
证明链接【证明来自于这篇博客】:https://blog.youkuaiyun.com/jiangpengna/article/details/38690023
题目描述
输入描述:
两个整数n(2<=n<=1000),a(2<=a<=1000)
输出描述:
一个整数.
#include <stdio.h>
bool a[1001];
int b[1001];
int size;
void Init(){
size =0;
for(int i=2;i<=1000;i++){
if(a[i]==true) continue;
b[size++]=i;
if(a[i]==false){
for(int j=i*i;j<=1000;j+=i){
a[j]=true;
}
}
}
} //求1~1000所有素数
int cnt1[1001],cnt2[1001];
int main(int argc, char *argv[])
{
int n,a;
while(scanf("%d%d",&n,&a)==2){
Init();
for(int i=0;i<size;i++){
cnt1[i]=cnt2[i]=0;
}
for(int i=0;i<size;i++){
int t=n;
while(t){
cnt1[i]+=t/b[i];
t=t/b[i];
}
}//求n的素数 ,在n!中对应因子的个数
int ans=123123123; //赋值为一个很大的数
for(int i=0;i<size;i++){
while(a%b[i]==0){
cnt2[i]++;
a/=b[i];
}//求a分解素因数后,各个素数的个数
if(cnt2[i]==0) continue;
if(cnt1[i]/cnt2[i]<ans) ans=cnt1[i]/cnt2[i];
}
printf("%d\n",ans);
}
return 0;
}
/*给定两个数m,n
求m!分解质因数后因子n的个数。
这道题涉及到了大数问题,如果相乘直接求的话会超出数据类型的范围。
下面给出一种效率比较高的算法,我们一步一步来。
m!=1*2*3*……*(m-2)*(m-1)*m
可以表示成所有和n倍数有关的乘积再乘以其他和n没有关系的
=(n*2n*3n*......*kn)*ohter other是不含n因子的数的乘积因为kn<=m 而k肯定是最大值所以k=m/n
=n^k*(1*2*......*k)*other
=n^k*k!*other
从这个表达式中可以提取出k个n,然后按照相同的方法循环下去可以求出k!中因子n的个数。
每次求出n的个数的和就是m!中因子n的总个数。*/
//1.求1-10000的素数,如果判断当前数x是素数,那么就从x*x开始标记其不是素数。
2.求n!中有多少个k(素数),那么就循环相除,结果相加即可。
3.如果两个数可以整除的话,那么就是它们的素因数可以抵消。
4.最后对应n!的素数个数对应a的素数个数数组相除,最小的就是k的值(至于这一点为什么,我也不知道==||)
//学到了不少。2h