#include <bits/stdc++.h>
using namespace std;
int p, q, r, s;
int main(int argc, char const *argv[])
{
while (cin >> p >> q >> r >> s)
{
q = min(p - q, q); s = min(r - s, s);
double sum = 1.0;
for (int i = 1; i <= q || i <= s; i++)
{
if (i <= q) sum = sum * (p - q + i) / i;
if (i <= s) sum = sum * i / (r - s + i);
}
printf("%.5f\n", sum);
}
return 0;
}
这样的写法很简洁,但这道题的核心在唯一分解定理上
#include <bits/stdc++.h>
using namespace std;
const int maxn = 1E4 + 10;
vector<int>primes;
int elem[maxn], p, q, r, s;
bool prim[maxn];
void getprim()
{
for (int i = 2; i < maxn; i++)
if (!prim[i])
{
primes.push_back(i);
for (int j = i * i; j < maxn; j += i)
prim[j] = 1;
}
}
void add_factorial(int n, int d)
{
for (int i = 1; i <= n; i++)
for (int j = 0, m = i; j < primes.size(); j++)
{
while (m % primes[j] == 0)
{
m /= primes[j];
elem[j] += d;
}
if (m == 1) break;
}
}
int main(int argc, char const *argv[])
{
getprim();
while (cin >> p >> q >> r >> s)
{
memset(elem, 0, sizeof(elem));
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], elem[i]);
printf("%.5lf\n", ans);
}
return 0;
}
唯一分解定理的运用