• 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;
    }
    
  • 相关阅读:
    Vmware 6.5:vmware vm高可用-vSphere HA & Fault Tlerance
    Redis 3.2.3: 集群3哨兵模式
    Mysql 5.7.18:主从复制,io优化
    Centos 7 x64 系统初始化
    javascript小实例,阻止浏览器默认行为,真的能阻止吗?支持IE和标准浏览器的阻止默认行为的方法
    javascript小实例,移动端页面中的拖拽
    javascript小实例,PC网页里的拖拽
    javascript小实例,在页面中输出当前客户端时间
    javascript小实例,编写一个方法,实现从n-m个数中随机选出一个整数
    javascript小实例,多种方法实现数组去重问题
  • 原文地址:https://www.cnblogs.com/Hayasaka/p/14294276.html
Copyright © 2020-2023  润新知