UVA 10375 - Choose and divide(数论)(组合数学)

来源:互联网 发布:windows无法打开此文件 编辑:程序博客网 时间:2024/06/06 15:39

题目大意:给出  p ,q, r, s这四个数,C(m, n) = m! / (m − n)! n!   ,让你求解   C(p, q)by C(r, s)  ,即两个阶乘相除。

思路:(   p!*s!*(r-s)!  ) /(  q!*(p-q)!*r!  )   

筛法求素数,唯一分解定理,用函数实现,从而求其各种阶乘,代码如下


#include<iostream>//唯一分解定理#include<cstdio>#include<cstring>#include<cmath>using namespace std;const int maxn = 1000005;int prime[maxn],flag[maxn],e[maxn],num=0;//筛法求素数void Init(){    for(int i=2;i<=maxn;i++)    {        if(flag[i])            continue;        prime[num++]=i;        for(int j=2;i*j<=maxn;j++)            flag[i]=1;    }}//计算因子的总个数void add_integer(int n,int d){    for(int i=0;i<num;i++)    {        while(n%prime[i]==0)        {            n/=prime[i];            e[i]+=d;//因为其指数为d,所以每个因子的指数为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(){    Init();    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<num;i++)            ans*=pow(prime[i],e[i]);        printf("%.5f\n",ans);    }    return 0;}

0 0
原创粉丝点击