数论题。如果知道相关公式的话那就是大水题了,我的做法比较土,600+ms飘过,路过的大牛有更好的解法的麻烦留个脚印啦~
首先是是C(m,n)=n!/((n-m)!*(m)!),因此只要知道这三个阶乘数所能包涵的每个素数个数即可。而求阶乘数的素数个数是有公式的,即:
n为阶乘数,p为目标素数
scanf("%d",&n);
int sum=0,temp=p;
while(n/temp)
{
sum+=n/temp;
temp*=p;
}
printf("%d/n",sum);
求出C(m,n)里每个素数的个数,再用组合公式即可,注意输出最终答案要用__int64。
以下是代码:
- #include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;
const int M=500;
bool prime[M];
int p[M],num;
int n,k; - void isprime()
{
int i,j;
num=0;
for(i=2;i<450;i++)
{
if(!prime[i]) p[num++]=i;
for(j=0;(j<num && i*p[j]<450);j++)
{
prime[i*p[j]]=1;
if(!(i%p[j])) break;
}
}
} - int stack[M];
- int main()
{
isprime();
while(scanf("%d%d",&n,&k)==2)
{
int i=0,top=0;
int m=n-k;
int cnt1,cnt2,cnt3;
while(n>=p[i])
{
cnt1=0;
cnt2=0;
cnt3=0;
int temp=p[i];
while(n/temp)
{
cnt1+=n/temp;
temp*=p[i];
}
temp=p[i];
while(m/temp)
{
cnt2+=m/temp;
temp*=p[i];
}
temp=p[i];
while(k/temp)
{
cnt3+=k/temp;
temp*=p[i];
}
cnt1=cnt1-(cnt2+cnt3);
if(cnt1)
stack[top++]=cnt1;
i++;
}
__int64 ans=1;
for(i=0;i<top;i++)
ans*=(stack[i]+1);
printf("%I64d/n",ans);
}
return 0;
}