题意:已知C(m,n)=m! / (n!*(m-n!)),输入整数p,q,r,s(p>=q,r>=s,p,q,r,s<=10000),计算C(p,q)/C(r,s)。输出保证不超过10^8,保留5位小数
#include<iostream>
#include<cstring>
#include<cmath>
#include<iomanip>
#define f(i,l,r) for(i=(l);i<=(r);i++)
using namespace std;
const int MAXN=2000,MAXM=10000;
int p,q,r,s;
int Prime[MAXN],inp[MAXM+5];
struct bign{
int w[MAXN],pos=0;
bign(){
memset(w,0,sizeof(w));
pos=0;
}
bign(int x){
int i;
memset(w,0,sizeof(w));
if(x==0) return;
f(i,1,Prime[0]){
while(x%Prime[i]==0){
x/=Prime[i];
w[i]++;
}
if(x==1){
pos=i;
break;
}
}
}
bign operator * (const bign &x){
int i;
bign ans;
ans.pos=max(pos,x.pos);
f(i,1,ans.pos){
ans.w[i]=w[i]+x.w[i];
}
return ans;
}
bign operator / (const bign &x){
int i;
bign ans;
ans.pos=max(pos,x.pos);
f(i,1,ans.pos){
ans.w[i]=w[i]-x.w[i];
}
return ans;
}
};
bign Ans;
void Init()
{
int i,j;
f(i,2,MAXM){
if(!inp[i]){
Prime[++Prime[0]]=i;
}
f(j,1,Prime[0]){
if(i*Prime[j]>MAXM) continue;
inp[i*Prime[j]]=1;
if(i%Prime[j]==0) break;
}
}
}
void Multi(int a,int flag)
{
int i;
f(i,2,a){
bign tmp;
tmp=bign(i);
if(flag==1) Ans=Ans*tmp;
else Ans=Ans/tmp;
}
}
int main()
{
int i;
double ans;
Init();
while(cin>>p>>q>>r>>s){
Ans=bign(0);
ans=1;
Multi(p,1);
Multi(s,1);
Multi(r-s,1);
Multi(q,-1);
Multi(p-q,-1);
Multi(r,-1);
f(i,1,Ans.pos){
ans*=pow(Prime[i],Ans.w[i]);
}
cout<<fixed<<setprecision(5)<<ans<<endl;
}
return 0;
}