zoukankan      html  css  js  c++  java
  • uva10375 Choose and Divide(唯一分解定理)

                                                              uva10375 Choose and Divide(唯一分解定理)

    题意:

          已知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)。输出保证不超过10^8,保留5位小数。

    分析:

        本题时间上基本上没有太大的限制,可以暴力求解C(m,n);

    #include<cstdio>
    #include<cstring>
    #include<iostream>
    using namespace std;
    int P, Q, R, S;
    void solve()
    {
        int i, j, k;
        double ans = 1.0;
        if(P - Q < Q)
            Q = P - Q;
        if(R - S < S)
            S = R - S;
        for(i = 1; i <= S || i <= Q; i ++)
        {
            if(i <= Q)
                ans = ans * (P - Q + i) / i;
            if(i <= S)
                ans = ans / (R - S + i) * i;
        }
        printf("%.5lf
    ", ans);
    }
    int main()
    {
        while(scanf("%d%d%d%d", &P, &Q, &R, &S) ==4)
            solve();
        return 0;
    }

      但是我们会发现当数据再大一些,就已超出了计算机整数的表示范围,所以本题

    我们使用唯一分解定理进行求解,通过将其分解为指数幂次相乘的形式即可

    #include <cstdio>
    #include <cstring>
    #include <cmath>
    #include <iostream>
    using namespace std;
    const int MAXN=10000;
    int prime[MAXN+1];
    int nprime;
    void getPrime(){
        int m=sqrt(MAXN+0.5);
        memset(prime,0,sizeof(prime));
        for(int i=2;i<=m;++i)if(!prime[i])
            for(int j=i*i;j<=MAXN;j+=i) prime[j]=1;
        nprime=0;
        for(int i=2;i<=MAXN;++i){
            if(!prime[i])
                prime[nprime++]=i;
        }
    }
    int e[MAXN+1];
    void add_integer(int n,int d){
        for(int i=0;i<nprime;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 main(){
        getPrime();
        int p,q,r,s;
        while(scanf("%d%d%d%d",&p,&q,&r,&s)!=EOF){
            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);
            int maxn=max(p,r);
            double ans=1;
            for(int i=0;i<=maxn;i++){
                ans*=pow(prime[i],e[i]);
            }
            printf("%.5lf
    ",ans);
        }
        return 0;
    }
  • 相关阅读:
    Solution: Win 10 和 Ubuntu 16.04 LTS双系统, Win 10 不能从grub启动
    在Ubuntu上如何往fcitx里添加输入法
    LaTeX 笔记---Q&A
    Hong Kong Regional Online Preliminary 2016 C. Classrooms
    Codeforces 711E ZS and The Birthday Paradox
    poj 2342 anniversary party
    poj 1088 滑雪
    poj 2479 maximum sum
    poj 2481 cows
    poj 2352 stars
  • 原文地址:https://www.cnblogs.com/fenhong/p/5436465.html
Copyright © 2011-2022 走看看