Choose and Divide,Uva10375(数论之分解质因数)
程序员文章站
2022-06-02 11:59:08
...
图片出自Uva截图。
题目大意:已知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 ).输出结果不超过 1e8 ,结果保留5位数。
解题思路:直接计算乘法结果太大,计算机不能存储,但是最终的结果是可以存储的。因此采用质因数分解法,将所有的要计算的数分解成素因数的形式,乘法即变成了素因数的幂的和。除法变成了素因数的幂的差。最后将所有的素因数全部相乘得到结果。
分解素因数的话,实现肯定是要打一张素数表的。不然怎么分解呢?使用Eratosthenes筛法产生素因数。分解一个数字则是依次试探能不能整除一个素数,能的话,这个素数就是这个数的素因数。可以整除几次,就是这个素因数的幂。
通过代码:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
using namespace std;
typedef long long LL ;
const LL MAXN = 10005;
LL len;
LL yuan[10005],sushu[10005];
LL sushuji()
{
LL p=0;
for(LL i=2;i<=MAXN;i++)
{
if(yuan[i]==0)
{
sushu[p++] = i;
for(LL j=i*i;j<=MAXN;j+=i)
{
if(yuan[j]==0)
yuan[j] = 1;
}
}
}
return p;
}
LL fenzi[10000];
void feijie( LL a ,LL d)
{
for(LL i=0;i<=len;i++)
{
while(a%sushu[i]==0)
{
fenzi[i]+=d;
a/=sushu[i];
}
if(a==1)
break;
}
}
void fun(LL n,LL d)
{
for(LL i=2;i<=n;i++)
{
feijie(i,d);
}
}
int main()
{
//freopen("in.txt","r",stdin);
//freopen("out.txt","w",stdout);
LL p,q,r,s;
len = sushuji();
while(scanf("%lld%lld%lld%lld",&p,&q,&r,&s)==4)
{
memset(fenzi,0,sizeof(fenzi));
fun(p,1);
fun(s,1);
fun(r-s,1);
fun(q,-1);
fun(r,-1);
fun(p-q,-1);
double sum = 1;
for(int i=0;i<len;i++)
{
sum*=pow(sushu[i],fenzi[i]);
}
printf("%.5lf\n",sum);
}
return 0;
}
上一篇: 雷峰塔门票多少钱 雷峰塔门票优惠政策
下一篇: 毕业旅行去哪好?十大毕业游景点推荐