• UVa10375


    /*UVa10375 - Choose and divide
    --考查素数因子唯一分解定理。将x!分解成素数因子,然后再进行相乘约分。考虑效率问题:组合数公式进行化简:
     C(m,n)=m*(m-1)*...(m-n+1)/n!来计算.
    */
    #define _CRT_SECURE_NO_DEPRECATE
    #include<iostream>
    #include<string.h>
    #include<algorithm>
    #include<cmath>
    using namespace std;
    const int maxn =10000+5;
    
    bool vis[maxn];
    int prime[maxn];  //10000素数表
    int pri[maxn];
    int pnum;  //素数个数
    
    //生成素数表
    int Euler(int n){
    	memset(vis, 0, sizeof(vis));
    	int phi = 0;
    	for (int i = 2; i <= n; i++){
    		if (!vis[i]){ prime[phi++] = i;};  //i是素数
    		for (int j = 0; j < phi&&i*prime[j] <= n; j++){
    			vis[i*prime[j]] = 1;   //筛去
    			if (i%prime[j] == 0)break;  //i是合数(当前是合法的),并且这个数已经被筛过
    		}
    	}
    	return phi; //返回素数个数
    }
    void add_integer(int n, int d){
    	for (int i = 0; i < pnum; i++){
    		while (n%prime[i] == 0){ n /= prime[i]; pri[i]+=d; }
    
    		if (n == 1)break;
    	}
    }
    //加入a*(a-1)*...(a-b+1)的素数因子
    void add_factorial(int a, int b, int d){
    	for (int i = 0; i < b;i++)
    		add_integer(a-i, d);
    }
    int main(){
    	int p, q, r, s;
    	pnum = Euler(10000);
    	while (~scanf("%d%d%d%d", &p, &q, &r, &s)){
    		memset(pri, 0, sizeof(pri));
    		q = min(q, p - q);
    		s = min(s, r - s);
    		add_factorial(p, q, 1);
    		add_factorial(r, s, -1);
    		if (s > q)add_factorial(s, s-q, 1);  //开始这里写出一个bug搞搞死我了
    		else add_factorial(q, q-s, -1);
    		double ans = 1.00;
    		for (int i = 0; i < pnum; i++)
    			ans *= pow(prime[i], pri[i]);
    		printf("%.5lf
    ",ans);
    	}
    	return 0;
    }
    

      

  • 相关阅读:
    个人冲刺二(2)
    个人冲刺二(1)
    三个和尚观后感
    每日总结
    个人冲刺(10)
    个人冲刺(9)
    个人冲刺(8)
    个人冲刺(7)
    个人冲刺(6)
    下次视频面试前把电脑摄像头擦干净吧
  • 原文地址:https://www.cnblogs.com/td15980891505/p/5803733.html
Copyright © 2020-2023  润新知