唯一分解定理+组合数学

UVA 10375

题意:P Q  R S,求C(p,q)/C(r,s).

两种方法:

第一种,数据比较水,一乘一除,不会溢出。

#include<stdio.h>
#include<iostream>
#include<algorithm>
using namespace std;
int main()
{
    double p,q,r,s;
    while(cin>>p>>q>>r>>s)
    {
        double sum=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)sum=sum*(p-q+i)/i;
            if(i<=s)sum=sum*i/(r-s+i);
        }
        printf("%.5f
",sum);
    }
}
View Code

第二种,唯一分解定理。

#include<stdio.h>
#include<iostream>
#include<algorithm>
#include<string.h>
#include<math.h>
using namespace std;
const int max_=10005;
int tot;
bool b[max_];
int e[max_];
int prime[max_];
void getprime()//素数表
{
    for(int i=2;i<max_;i++)
    {
        if(!b[i]){
           prime[++tot]=i;
        for(int j=i+i;j<max_;j+=i)
        {
            b[j]=1;
        }
      }
    }
}
void add_integer(int n,int d)//d为1即乘,-1即除。
{
    for(int i=1;i<=tot;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 pow_q(int x,int n)
{
    int res=1;
    while(n>0)
    {
        if(n&1)
            res*=x;
        x=x*x;
        n>>=1;
    }
    return res;
}*/
int main()
{
    int p,q,r,s;
    getprime();
    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 sum=1.0;
        for(int i=1;i<=tot;i++)
        {
            if(e[i])
            {
                sum*=pow(prime[i],e[i]);
            }
        }
        printf("%.5f
",sum);
    }
}
View Code
原文地址:https://www.cnblogs.com/linhaitai/p/9974311.html