Choose and Divide UVa10375 题解

  两个超大组合数相除。解法是分解质因数,用数组记录每个质因数称或除的次数,最后直接遍历数组计算即可

#include<iostream>
#include<cstdio>
#include<cmath>
#include<vector>
using namespace std;
void Fact(int n, int opt, vector<int> primes, vector<int>& fact);
void addFact(int n, int opt, vector<int> primes, vector<int>& fact);
int main()
{
    int p, q, r, s;
    while (cin >> p >> q >> r >> s)
    {
        vector<int> nums(10001, 1);
        vector<int> primes(1);
        //获取1-10000的所有质数
        for (int i = 2; i <= 10000; ++i)
        {
            if (nums[i] == 1)
            {
                primes.push_back(i);
                for (int i1 = 1; i*i1 < 10000; ++i1)
                {
                    nums[i*i1] = 0;
                }
            }
        }
        vector<int> fact(primes.size(), 0);
        addFact(p, 1, primes, fact);
        addFact(q, -1, primes, fact);
        addFact(p - q, -1, primes, fact);
        addFact(r, -1, primes, fact);
        addFact(s, 1, primes, fact);
        addFact(r - s, 1, primes, fact);
        double answer = 1;
        for (int i = 1; i < fact.size(); ++i)
        {
            if (fact[i] != 0)
            {
                answer *= pow(primes[i], fact[i]);
            }
        }
        printf("%.5lf\n", answer);
    }
    return 0;
}

void Fact(int n,int opt,vector<int> primes,vector<int>& fact)
{
    for (int i = 1; i < primes.size(); ++i)
    {
        while (!(n%primes[i]))
        {
            n = n / primes[i];
            fact[i]+=opt;
        }
        if (n == 1)
        {
            break;
        }
    }
}

void addFact(int n, int opt, vector<int> primes, vector<int>& fact)
{
    for (int i = 1; i <= n; ++i)
    {
        Fact(i, opt, primes, fact);
    }
}

  (用JAVA的大数好像直接算就可以而且不会超时)

时间: 2024-11-05 19:38:52

Choose and Divide UVa10375 题解的相关文章

UVA10375 Choose and divide 质因数分解

质因数分解: Choose and divide Time Limit: 3000MS   Memory Limit: Unknown   64bit IO Format: %lld & %llu Submit Status Description Problem D: Choose and divide The binomial coefficient C(m,n) is defined as m! C(m,n) = -------- n!(m-n)! Given four natural n

UVA 10375 Choose and divide(数论)

The binomial coefficient C(m,n) is defined as m! C(m,n) = -------- n!(m-n)! Given four natural numbers p, q, r, and s, compute the the result of dividing C(p,q) by C(r,s). The Input Input consists of a sequence of lines. Each line contains four non-n

10375 - Choose and divide(唯一分解定理的运用 eratosthenes构造素数表)

我觉得数学类的题目,每一道都有很好的解决方法,都很有保存的意义和价值. 这道题目里面,巧妙地运用了 唯一分解定理,辅以素数的eratosthenes筛法构造,很好地解决了题目.值得思考和深入的学习. #include<cstdio> #include<cstring> #include<cmath> #include<vector> #include<algorithm> using namespace std; vector<int>

【暑假】[数学]UVa 10375 Choose and divide

UVa 10375 Choose and divide 题目: http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=19601 思路: maxn=10000 如果计算maxn!再保存的话显然装不下. 但答案由阶乘的积或商组成,所以可以用唯一分解定理求解.大题思路就是把目前答案的质因子的指数用数组e保存,乘除都对e操作. 需要注意的是筛法求素数优化后的写法. 代码: 1 #include<iostream> 2 #include

UVA 10375 Choose and divide(唯一分解定理)

这么大数的乘法.除法运算,肯定不能先全部乘起来,我的思路是计算出分子.分母上的每个数的个数(因为最大的数为10000,可以开一个数组记录个数). 利用了随机数方法终于知道错在哪了,中间如果出现连乘还是会溢出,这点没想到,以下是我的溢出代码: #include<stdio.h> #include<math.h> #include<iostream> #include<string.h> #include<stdlib.h> #include<

UVa10375 - Choose and divide

紫薯上刘汝佳写的啥玩意啊,看不懂看不懂 google之 发现这么一个公式: C(n,k)=C(n,k−1)∗(n−k+1)/k 有了这个公式,那么我们就可以对其进行递推了 C(p,q)=(p-q+1)/q*C(p,q-1) 即: for (i=1;i<=q;i++) ans = ans * (p-i+1) / i; 边乘边除可以避免越界,代码如下: #include<cstdio> #include<cstring> #include<iostream> #inc

UVa 10375 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(p, q)\)和\(C(r, s)\)是肯定不可能的, C++存不下这么大的

Choose and divide

The binomial coefficient C(m,n) is defined as m! C(m,n) = -------- n!(m-n)! Given four natural numbers p, q, r, and s, compute the the result of dividing C(p,q) by C(r,s). The Input Input consists of a sequence of lines. Each line contains four non-n

UVA 10375 Choose and divide

紫上给得比较奇怪,其实没有必要用唯一分解定理.我觉得这道题用唯一分解只是为了表示大数. 但是分解得到的幂,累乘的时候如果顺序很奇怪也可能溢出.其实直接边乘边除就好了.因为答案保证不会溢出, 设定一个精度范围,如果中间结果超过了精度范围就保存起来,最后sort一遍从两端同时乘就不会溢出了. /********************************************************* * --------------Tyrannosaurus--------- * * aut