• UVA 10375


    The binomial coefficient C(m,n) is defined as C(m,n)=
    m!
    --------
    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).

    Input

    Input consists of a sequence of lines. Each line contains four non-negative integer numbers giving values for p, q, r, and s, respectively, separated by a single space. All the numbers will be smaller than 10,000 with p>=q and r>=s.

    Output

    For each line of input, print a single line containing a real number with 5 digits of precision in the fraction, giving the number as described above. You may assume the result is not greater than 100,000,000.

    Sample Input

    10 5 14 9
    93 45 84 59
    145 95 143 92
    995 487 996 488
    2000 1000 1999 999
    9998 4999 9996 4998

    Sample Output

    0.12587
    505606.46055
    1.28223
    0.48996
    2.00000
    3.99960

    题目大意:
    这道题是两个组合数相除,求C(p,q)/C(r,s)。

    解题思路:
    因为范围有1e4,所以常规做数据范围是装不下的,我们要用唯一分解定理把这个式子分解成多个质数然后不断约分即可。
    唯一分解定理:任何一个大于1的自然数 N,N一定可以唯一分解成有限个质数的乘积。(百度百科)
    我们先把这个范围内的素数筛出来(我用的是埃氏筛法),用一个数组去存这些数的状态,然后开始对分子分母的每一个数进行分解,看看他对最后的答案贡献了几个质数,把这个式子整理一下,就可以得到分子分母,因为要约分,所以对于分子,每一个出现的质数的数量都+1,分母每个出现的质数的数量都-1,最后就可以得到这个质数最终的个数了。AC代码:

    #include <cstdio>
    #include <iostream>
    #include <algorithm>
    #include <cstring>
    #include <cmath>
    using namespace std;
    using LL = long long;
    const int _max=1e4+50;
    LL a[_max],num[_max],cnt=0;
    bool prime[_max];
    void isprime()
    {
    	memset(prime,false,sizeof prime);
    	for(int i=2;i<=_max;i++)
    	  if(!prime[i])
    	  {
    		  num[cnt++]=i;//num用来存放第cnt个质数是多少
    		  for(int j=i*2;j<=_max;j+=i)
    		    prime[j]=true;
    	  }
    }
    void solve(int n,int d)//对该数进行分解质因子
    {
    	for(int i=0;i<cnt;i++)
    	{
    		while(n%num[i]==0)
    		{
    			n/=num[i];
    			a[i]+=d;//第 i 个质数要+1或-1
    		}
    		if(n==1)//不加会TLE,我们要在n==1的时候提前退出循环,不然遍历的次数太多
    		 return;
    	}
    }
    int main()
    {
    	double ans;
    	int p,q,r,s;
    	isprime();
    	while(cin>>p>>q>>r>>s)
    	{
    		ans=1;
    		memset(a,0,sizeof a);
    		for(int i=1;i<=p;i++) solve(i,1);//分子+1
    		for(int i=1;i<=r-s;i++) solve(i,1);
    		for(int i=1;i<=s;i++) solve(i,1);
    
    		for(int i=1;i<=p-q;i++) solve(i,-1);//分母-1
    		for(int i=1;i<=q;i++) solve(i,-1);
    		for(int i=1;i<=r;i++) solve(i,-1);
    		for(int i=0;i<cnt;i++)
    		  if(num[i])
    		    ans*=pow(num[i],a[i]);
    		printf("%.5lf
    ",ans);
    	}
    	return 0;
    }
    
  • 相关阅读:
    excel 上标和下标
    Excel之tab键
    Excel分数、小数、身份证的录入
    excel快速访问工具栏和自定义选项卡
    excel如何快速实现数据区域的框选
    excel 如何快速实现绝对引用
    INT函数和ROUND
    Excel Vlookup 列查找函数
    excel合并同类项去重求和功能
    VBA 一个很神奇的东西
  • 原文地址:https://www.cnblogs.com/Hayasaka/p/14294276.html
Copyright © 2020-2023  润新知