题目:题意:已知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<cstdio>
#include<cmath>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<vector>
#include<sstream>
#include<map>
#include<stack>
#include<queue>
using namespace std;
int find_[10001][10001],p,q,r,s; //find[i][j] 指 i! 中第j个质数的幂。
int vis[10001];
int mother[1231],son[1231];
double ans = 1.0;
vector<int> prime;
int main(){
memset(find_, 0, sizeof(find_));
int m = sqrt(10001+0.5);
for(int i = 2;i<=m;i++) if(!vis[i])
for(int j = i*i;j<=10000;j+=i) vis[j] = 1; //筛法求质数
prime.push_back(0);
for(int i = 2;i<=10000;i++) if(!vis[i]) prime.push_back(i); //建立质数序列
for(int i = 2;i<=10000;i++){
memcpy(find_[i], find_[i-1], sizeof(find_[2]));
int x = i;
for(int j = 1;x!=1;j++){
int q = 0,num = prime[j];
while(x%num==0){
q++;
x/=num;
}
find_[i][j] += q;
}
}
while(scanf("%d%d%d%d",&p,&q,&r,&s)!=EOF){
ans = 1.0;
int a = r-s,b = p-q;
memset(mother, 0, sizeof(mother));
memset(son, 0, sizeof(son));
for(int i = 1;i<=1230;i++){ //10000内共1230个质数
mother[i] = find_[p][i] + find_[s][i] + find_[a][i]; //第i个质数的分母幂次
son[i] = find_[q][i] + find_[r][i] + find_[b][i];//第i个质数的分子幂次
mother[i] = mother[i] - son[i];
}
for(int i = 1;i<=1230;i++) ans *= pow(prime[i], mother[i]);
printf("%.5f\n",ans);
}
return 0;
}