组合数
题目
题目就是求出两个大组合数的比值,精度保留小数点后五位。用分解质因数做
#include<iostream>
#include<cmath>
#include<algorithm>
#include<cstring>
using namespace std;
int num[100010];
void cal(int d,int flag)
{
if(flag)
{
for(int i=2;i<=d;i++)
{
while(d%i==0)
{
num[i]++;
d/=i;
}
}
}
else
{
for(int i=2;i<=d;i++)
{
while(d%i==0)
{
num[i]--;
d/=i;
}
}
}
}
int main()
{
int p,q,r,s;
while(scanf("%d%d%d%d",&p,&q,&r,&s)!=EOF)
{
memset(num,0,sizeof(num));
for(int i=p-q+1;i<=p;i++)
cal(i,1);
for(int i=2;i<=q;i++)
cal(i,0);
for(int i=r-s+1;i<=r;i++)
cal(i,0);
for(int i=2;i<=s;i++)
cal(i,1);
double ans=1.0;
for(int i=2;i<=max(p,r)+10;i++)
if(num[i])
ans*=pow(i*1.0,num[i]);
printf("%.5f\n",ans);
}
return 0;
}
另一种办法:边乘边除防止爆精度
#include<iostream>
using namespace std;
int main()
{
int p,q,r,s;
while(scanf("%d%d%d%d",&p,&q,&r,&s)!=EOF)
{
double ans=1.0;
for(int i=1;i<=q||i<=s;i++)
{
if(i<=q)
{
ans*=(double)(p-i+1)/i;
}
if(i<=s)
{
ans/=(double)(r-i+1)/i;
}
}
printf("%.5f\n",ans);
}
return 0;
}