UVA10375 Choose and divide(唯一分解定理)
UVA - 10375 Choose and divide
Description
The binomial coefficient C(m, n) is defined as
C(m, n) = m!/((m − n)! n!)
Given four natural numbers p, q, r, and s, compute the the result of dividing C(p, q) by C(r, s).
Input
Input consists of a sequence of lines. Each line contains four non-negative integer numbers giving values for p, q, r, and s, respectively, separated by a single space. All the numbers will be smaller than 10,000 with p ≥ q and r ≥ s.
Output
For each line of input, print a single line containing a real number with 5 digits of precision in the fraction,
giving the number as described above. You may assume the result is not greater than 100,000,000.
Sample Input
10 5 14 9
93 45 84 59
145 95 143 92
995 487 996 488
2000 1000 1999 999
9998 4999 9996 4998
Sample Output
0.12587
505606.46055
1.28223
0.48996
2.00000
3.99960
题解
题意
已知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位小数
思路
唯一分解定理的题目,维护素数数组e,表示当前结果中唯一分解定理的各个素数的指数。然后最后对该指数进行计算即可。
代码
#pragma comment(linker, "/STACK:1024000000,1024000000")
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<string>
#include<vector>
#include<stack>
#include<bitset>
#include<cstdlib>
#include<cmath>
#include<set>
#include<list>
#include<deque>
#include<map>
#include<queue>
using namespace std;
typedef long long ll;
const double PI = acos(-1.0);
const double eps = 1e-6;
const int INF = 0x3f3f3f3f;
#define REP(i,n) for(int i=0;i<(n);i++)
const int MAXN = 1e4+10;
int e[MAXN];
bool prime[MAXN];
vector<int> primes;
void pre(){
for(int i = 2; i < MAXN; i ++) prime[i] = true;
for(int i = 2; i*i < MAXN; i ++){
if(prime[i]==true){
for(int j = i*i; j < MAXN; j += i){
prime[j] = false;
}
}
}
for(int i=2;i<=MAXN;i++){
if(prime[i]==true) primes.push_back(i);
}
}
void add_integer(int n,int d){
for(int i=0;i<primes.size();i++){
while(n%primes[i]==0){
n/=primes[i];
e[i]+=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(){
pre();
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;
for(int i=0;i<primes.size();i++)
ans *= pow(primes[i],e[i]);
printf("%.5lf\n",ans);
}
return 0;
}

浙公网安备 33010602011771号