Choose and divide
Time Limit: 3000MS Memory Limit: Unknown
Description:
The binomial coefficient C(m, n) is defined as
Given four natural numbers p, q, r, and s, compute the the result of dividing C(p, q) by C(r, s).
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.
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
代码实现:
方法一:
#include <iostream>
#include <stdio.h>
#include <string.h>
#include <algorithm>
using namespace std;
int main()
{
int p, q, r, s;
while(~scanf("%d%d%d%d",&p,&q,&r,&s))
{
if(p - q < q)///q和p-q中较大值的阶乘和p的阶乘消去
q = p - q;
if(r - s < s)
s = r - s;
double ans = 1.0;
for(int i = 1;i <= q || i <= s; i++)
{
if(i <= q)
ans = ans* (p - q + i) / i;
if(i<=s)
ans = ans / (r - s + i) * i;
}
printf("%.5f\n",ans);
}
return 0;
}
方法二(唯一分解定理):
#include <iostream>
#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <math.h>
#include <vector>
using namespace std;
vector<int>prime;
const int Max=10005;
int e[Max];
bool vis[Max];
void is_prime(int n)///筛选素数
{
int m = sqrt(n + 0.5);
memset(vis,false,sizeof(vis));
for(int i = 2; i <= m; i++)
{
for(int j = i*i; j <= n; j += i)
vis[j] = true;
}
}
void get_prime(int n)
{
for(int i = 2;i <= n; i++)
{
if(!vis[i])
prime.push_back(i);
}
}
void add_integer(int n,int d)
{
for(int i = 0;i < prime.size(); i++)
{
while(n % prime[i] == 0)
{
n /= prime[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()
{
is_prime(Max-1);
get_prime(Max-1);
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 < prime.size(); i++)
ans *= pow(prime[i],e[i]);
printf("%.5f\n",ans);
}
return 0;
}