题目链接
题意
计算C(p,q)/C(r,s), (p>=q,r>=s,p,q,r,s<=10000)
题解
思路1:
唯一分解定理,C(m,n) = m!/(n!(m-n)!)
to solve c(p,q) / c(r,s) = p! * s! * (r-s)! / r! * q! * (p-q)!
将每个阶乘分解到e[]数组中。e数组是阶数数组。
最后e数组就是答案。
思路2:
边乘边除。
代码
思路1代码
/**
* using only decomposition theorem
* to solve c(p,q) / c(r,s) = p!*s!*(r-s)! / r!*q!*(p-q)!
* take every ! to break down to the array e[]
*
* ans the ans is e[]
*/
#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<vector>
#include<cmath>
using namespace std;
const int maxn = 1e4+10;
vector<int> primes;
int e[maxn];
bool vis[maxn];
void Creat()
{
memset(vis,true,sizeof(vis));
primes.clear();
vis[0] = vis[1] = 0;
for(int i=2;i<maxn;i++)
{
if(vis[i]){
primes.push_back(i);
}
for(int j=0;j<(int)primes.size() && primes[j]*i<maxn ;j++)
{
vis[i*primes[j]] = false;
if(i%primes[j] == 0) break;
}
}
}
void add_e(int x,int d)
{
for(int i=0;i<(int)primes.size();i++)
{
while(x % primes[i] == 0) {
e[i] += d;
x /= primes[i];
}
if( x == 1 ) break;
}
}
void add_factorial(int x,int d)
{
for(int i=x;i>1;i--)
add_e(i,d);
}
int main()
{
Creat();
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(s,1);
add_factorial(r-s,1);
add_factorial(r,-1);
add_factorial(q,-1);
add_factorial(p-q,-1);
double ans = 1.0;
for(int i=0;i<(int)primes.size();i++)
ans *= pow(primes[i],e[i]);
printf("%.5lf\n",ans);
}
return 0;
}
思路2代码
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int main()
{
int p,q,r,s;
while(cin>>p>>q>>r>>s)
{
double ans = 1.0;
if(p-q < q) q = p - q;
if(r-s < s) s = r - s;
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;
}