根据算术基本定理把所有的n!p!......都分解成质数,用数组e[]保存下指数,乘的话就是加,除的话就是减,最后再算出来即可。
#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<cctype>
#define N 10005
using namespace std;
double ans=1;
int prime[N],e[N],mark[N];
int p,q,r,s;
void get_prime(){//欧拉筛
for (int i=2;i<N;i++){
if (!mark[i]){mark[i]=1;prime[++prime[0]]=i;}
for (int j=1;j<=prime[0]&&i*prime[j]<N;j++){
mark[i*prime[j]]=1;
if (!(i%prime[j])) break;
}
}
}
void break_down(int n,int d){
for (int i=1;i<=prime[0];i++){
for (;!(n%prime[i]);n/=prime[i]) e[i]+=d;
if (n==1) break;
}
}
void handle(int n,int d){for (int i=1;i<=n;i++) break_down(i,d);}
int main(){
get_prime();
for (;~scanf("%d%d%d%d",&p,&q,&r,&s);){
ans=1;memset(e,0,sizeof(e));
handle(p,1);
handle(q,-1);
handle(p-q,-1);
handle(r,-1);
handle(s,1);
handle(r-s,1);
for (int i=1;i<=prime[0];i++) ans*=pow(prime[i],e[i]);
printf("%.5lf\n",ans);
}
return 0;
}