题意:已知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<stdio.h>
#include<string.h>
#include<iostream>
#include<math.h>
#include<stdlib.h>
#include<ctype.h>
#include<vector>
#include<algorithm>
#define CPY(A,B)memcpy(A,B,sizeof(A))
typedef long long LL;
typedef unsigned long long uLL;
const int MOD=1e9+7;
const int INF=0x3f3f3f3f;
const LL INFF=0x3f3f3f3f3f3f3f3fLL;
const double EPS=1e-9;
const double OO=1e20;
const double PI=acos (-1.0);
int dx[]= {0,1,0,-1};
int dy[]= {1,0,-1,0};
int gcd (const LL &a,const LL &b) {return b==0?a:gcd (b,a%b);}
using namespace std;
const int MAXN=10000;
int Prime[MAXN],psize;
void INIT() {
int m=sqrt (MAXN+0.5);
memset (Prime,0,sizeof Prime);
for (int i=2; i<=m; ++i) {
if (!Prime[i]) {
for (int j=i*i; j<=MAXN; j+=i) {
Prime[j]=1;
}
}
}
psize=0;
for (int i=2; i<MAXN; ++i) {
if (!Prime[i]) {
Prime[psize++]=i;
}
}
}
int e[MAXN];//当前结果的唯一分解式中各个素数的指数
void add_int (int n,int d) {
for (int i=0; i<psize; ++i) {
while (n%Prime[i]==0) {
n/=Prime[i];
e[i]+=d;
}
if (n==1) { break; }
}
}
inline void add_f (int n,int d) {
for (int i=1; i<=n; ++i) {
add_int (i,d);
}
}
//d=0表示乘,d=-1表示除
int main() {
INIT();
int p,q,r,s;
while (scanf ("%d%d%d%d",&p,&q,&r,&s) !=EOF) {
memset (e,0,sizeof e);
add_f (p,1);
add_f (q,-1);
add_f (p-q,-1);
add_f (r,-1);
add_f (s,1);
add_f (r-s,1);
int maxn=max (p,r);
double ans=1;
for (int i=0; i<=maxn; ++i) {
ans*=pow (Prime[i],e[i]);
}
printf ("%.5f\n",ans);
}
return 0;
}