通过题目给的定义C(m,n)=m!/(n!(m-n)!),以及题目要求计算的C(p,q)/C(r,s)联立可得
p!s!(r-s)!/q!r!(p-q)!
看到这个式子,我们可以分析一下,我们可以将每个阶乘,都通过唯一分解定理将它们分解
(具体教程可见:https://blog.csdn.net/qq_39439314/article/details/78270905)
所以,首先我们应该先求出10000以内的所有素数,然后通过唯一分解定理将各个阶乘都分解,求出所有存在的可用质数以及对应的质数的指数
p!s!(r-s)!/q!r!(p-q)!分母那一部分的阶乘分解时,对应质数增加时我们可以乘以一个-1,而分子对应的分解时,我们可以乘以一个1
最后再将所有的pow(质数,对应指数)相乘,得到相应的结果,结果保留五位小数。
1 #include<iostream> 2 #include<string.h> 3 #include <iomanip> 4 #include<cmath> 5 6 typedef long long ll; 7 const int maxn = 10000 + 10; 8 9 int primes[maxn]; 10 bool p[maxn]; 11 int e[maxn]; 12 int tol = 0; 13 14 using namespace std; 15 16 void find_primes(int n); 17 void add_factorial(int n, int d); 18 19 int main() 20 { 21 ios::sync_with_stdio(false); 22 cin.tie(0); 23 cout.tie(0); 24 25 int p, q, r, s; 26 find_primes(maxn);//用筛素法打出素数表 27 28 while (cin >> p >> q >> r >> s) 29 { 30 memset(e, 0, sizeof(e)); 31 add_factorial(p, 1); 32 add_factorial(s, 1); 33 add_factorial(r-s, 1); 34 add_factorial(q, -1); 35 add_factorial(r, -1); 36 add_factorial(p-q,-1); 37 38 double total = 1; 39 40 for (int i = 0; i < tol; i++) 41 total *= pow(primes[i], e[i]); 42 cout << fixed << setprecision(5) << total << endl; 43 } 44 45 46 return 0; 47 } 48 49 void find_primes(int n)//筛素法 50 { 51 memset(p, false, sizeof(p)); 52 53 for (int i = 2; i <= n; i++) 54 { 55 if (!p[i]) 56 { 57 primes[tol++] = i; 58 for (int j = i * i; j <= n; j += i) 59 p[j] = true; 60 } 61 } 62 } 63 64 void add_factorial(int n, int d)//唯一分解定理对n!质因数分解的应用 65 { 66 for (int i = 0; i < tol; i++) 67 { 68 if (primes[i] > n) 69 break; 70 ll t = primes[i]; 71 while (t <= n) 72 { 73 e[i] += d * n / t; 74 t *= primes[i]; 75 } 76 } 77 }
原文地址:https://www.cnblogs.com/cdplay/p/9419931.html
时间: 2024-10-12 07:35:56