zoukankan      html  css  js  c++  java
  • 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;
    }
    
  • 相关阅读:
    使用C#实现DHT磁力搜索的BT种子后端管理程序+数据库设计(开源)
    便携版WinSCP在命令行下同步文件夹
    ffmpeg (ffprobe)分析文件关键帧时间点
    sqlite删除数据或者表后,回收数据库文件大小
    ubuntu 20.04下 freeswitch 配合 fail2ban 防恶意访问
    ffmpeg使用nvenc编码的结论记录
    PC版跑跑卡丁车 故事模式 亚瑟传说章节 卡美洛庆典 2阶段 心灵之眼 攻略
    There was an error loading or playing the video
    Nvidia RTX Voice 启动报错修复方法
    火狐浏览器 关闭跨域限制
  • 原文地址:https://www.cnblogs.com/Hayasaka/p/14294276.html
Copyright © 2011-2022 走看看