1.题目描述:点击打开链接
2.解题思路:本题让计算两个组合数的商,既可以直接利用公式,也可以利用唯一分解定理:事先计算10000以内的所有素数,然后计算组合数分解后各个素数的幂,用数组e保存指数即可。这里计算指数时可以利用数论中求n!分解式中各个素因数指数的公式。
3.代码:
(利用唯一分解定理)
#define _CRT_SECURE_NO_WARNINGS #include<iostream> #include<algorithm> #include<string> #include<sstream> #include<set> #include<vector> #include<stack> #include<map> #include<queue> #include<deque> #include<cstdlib> #include<cstdio> #include<cstring> #include<cmath> #include<ctime> #include<functional> using namespace std; #define maxn 10000+10 int vis[maxn]; int e[maxn]; vector<int>primes; void init()//计算10000以内的素数 { int m = sqrt(maxn + 0.5); for (int i = 2; i <= m; i++) if (!vis[i]) for (int j = i*i; j <= 10000; j += i) vis[j] = 1; for (int i = 2; i <= 10000; i++) if (!vis[i]) primes.push_back(i); } void add_factorial(int n, int d)//计算指数并添加到数组e { int tmp = n; for (int i = 0; i < primes.size(); i++) { if (n / primes[i] == 0)break; int sum = 0; int x = primes[i]; while (n / x>0) { sum += n / x; x = x*primes[i]; } if (d == 1) e[i] += sum; else e[i] -= sum; } } int main() { //freopen("test.txt", "r", stdin); int p, q, r, s; init(); while (cin >> p >> q >> r >> s) { memset(e, 0, sizeof(e)); add_factorial(p, 1); add_factorial(q, -1); add_factorial(p - q, -1); add_factorial(r, -1); add_factorial(s, 1); add_factorial(r - s, 1); double ans = 1; for (int i = 0; i < primes.size(); i++) ans *= pow(primes[i] , e[i]); printf("%.5lf\n", ans); } return 0; }
(利用公式直接计算)
#include <cstdio> #include <algorithm> using namespace std; int main () { int p, q, r, s; while (scanf ("%d%d%d%d", &p, &q, &r, &s) != EOF) { q = min (q, p - q); s = min (s, r - s); double ans = 1.0; for (int i = 1; i <= q || i <= s; i++) { if (i <= q) ans = ans * (p - i + 1) / i; if (i <= s) ans = ans * i / (r - i + 1); } printf ("%.5lf\n", ans); } return 0; }
时间: 2024-11-08 14:34:05