UVa 10780 幂和阶乘 求n!中某个因子的个数
题意:
输入两个整数m和n(m<5000,n<10000),求最大的整数k使得m^k是n!的约数
分析:
显然这题的做法是把m分解质因子,每个质因子的个数是cnt[i],然后求一下n!中m的质因子的个数num[i],那么答案就是ans=min(ans,num[i]/cnt[i])。求n!中某个因子的个数,因为n<10000,所以直接枚举每个数i(i< x)统计即可。
const int N=1e4+9;
vector<int>fac;
int cnt[N],num[N];
void prime_fac(int n)
{
fac.clear();
for(int i=2;i*i<=n;i++){
if(n%i==0){
fac.push_back(i);
cnt[i]=1;
n/=i;
while(n%i==0)cnt[i]++,n/=i;
}
}
if(n>1){
fac.push_back(n);
cnt[n]=1;
}
}
int m,n,T;
int main()
{
scanf("%d",&T);
for(int cas=1;cas<=T;cas++){
memset(num,0,sizeof(num));
memset(cnt,0,sizeof(cnt));
scanf("%d%d",&m,&n);
prime_fac(m);
for(int i=2;i<=n;i++){
for(int j=0;j<fac.size();j++){
int x=i;
while(x%fac[j]==0){
x/=fac[j];
num[fac[j]]++;
}
}
}
int ans=100000000;
bool flag=1;
for(int i=0;i<fac.size();i++){
if(num[fac[i]]<cnt[fac[i]]){
flag=0;break;
}
ans=min(ans,num[fac[i]]/cnt[fac[i]]);
}
printf("Case %d:\n",cas);
if(flag)printf("%d\n",ans);
else puts("Impossible to divide");
}
return 0;
}
做完这题后搜题解,看到大多数人都是用公式求n!中某个因子的个数,果然自己数论还是做得少啊!QAQ
求n!中某个因子的个数:
n!=(k^m)*(m!)*a 其中k是该因子,m=n/k,a是不含因子k的数的乘积
下面推导这个公式 :
n!=n*(n-1)*(n-2)*......3*2*1
=(k*2k*3k.....*mk)*a a是不含因子k的数的乘积,显然m=n/k;
=(k^m)*(1*2*3...*m)*a
=k^m*m!*a
接下来按照相同的方法可以求出m!中含有因子k的个数。
因此就可以求除n!中因子k的个数
int count(int n,int k)
{
int num=0;
while(n){
num+=n/k;
n/=k;
}
return num;
}