思路:这道题是算法竞赛紫书第十章第316页的一个习题,上面有主要的代码;
方法:因为含有阶乘,直接运算,数太大,一定会溢出的,而书上的方法,避免了这种溢出,而是采用分解的方法,利用数论中合数可以分解若干个素数相乘的形式,相乘或者相除时,只需在对应素数的指数相加减,即可。我们可以另开一个数组,用来对应存素数的指数。(代码简单易懂)。
#include <iostream>
#include <string.h>
#include <math.h>
#include <vector>
#include <stdio.h>
#include <algorithm>
using namespace std;
int e[100000];
bool book[100000];
vector<int>prime;
void Prime()
{
for(int i=2;i<=10000;i++)
{
if(book[i]==false)prime.push_back(i);
for(int j=i*i;j<=10000;j+=i)
if(book[j]==false)
book[j]=true;
}
}
void Add_factorial(int n,int d)
{
for(int i=0; i<prime.size()&&n>1; i++)
while(n%prime[i]==0)
{
e[i]+=d;
n=n/prime[i];
}
}
void add_factorial(int m,int k)
{
for(int i=1;i<=m;i++)
Add_factorial(i,k);
return ;
}
int main()
{
int p,q,r,s;
memset(book,false,sizeof(book));
Prime();
while(cin>>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 cont=1.0;
for(int i=0;i<prime.size(); i++)
cont*=pow(prime[i],e[i]);
printf("%.5lf\n",cont);
}
return 0;
}