题目大意:给出 p ,q, r, s这四个数,C(m, n) = m! / (m − n)! n! ,让你求解 C(p, q) by C(r, s) ,即两个阶乘相除。
思路:( p!*s!*(r-s)! ) /( q!*(p-q)!*r! )
筛法求素数,唯一分解定理,用函数实现,从而求其各种阶乘,代码如下
#include<iostream>//唯一分解定理 #include<cstdio> #include<cstring> #include<cmath> using namespace std; const int maxn = 1000005; int prime[maxn],flag[maxn],e[maxn],num=0; //筛法求素数 void Init() { for(int i=2;i<=maxn;i++) { if(flag[i]) continue; prime[num++]=i; for(int j=2;i*j<=maxn;j++) flag[i]=1; } } //计算因子的总个数 void add_integer(int n,int d) { for(int i=0;i<num;i++) { while(n%prime[i]==0) { n/=prime[i]; e[i]+=d;//因为其指数为d,所以每个因子的指数为d } if(n==1) break; } } //计算阶乘和除以阶乘 void add_factorial(int n,int d) { for(int i=1;i<=n;i++) add_integer(i,d); } int main() { Init(); int p,q,r,s; while(~scanf("%d%d%d%d",&p,&q,&r,&s)) { memset(e,0,sizeof(e)); add_factorial(p, 1); add_factorial(q, -1); add_factorial(p-q, -1); add_factorial(r, -1); add_factorial(s, 1); add_factorial(r-s, 1); double ans = 1.0; for(int i=0;i<num;i++) ans*=pow(prime[i],e[i]); printf("%.5f\n",ans); } return 0; }