c++代码实现 小明参加一个比赛,规则是:每组卡牌有十张且点数为 1 到 10,现有 n 组卡牌,选手要在 n 组卡牌中,每组抽取一张,共抽 n 张;若 n 张卡牌的总点数大于 k 则小明获胜,求小明获胜的概率有多大?
时间: 2024-02-11 09:07:43 浏览: 103
请看下面的代码实现:
```c++
#include <iostream>
#include <cmath>
using namespace std;
long long binomial(int n, int m);
int main() {
int n, k;
cin >> n >> k;
// 计算不满足条件的抽卡方案数
long long not_win = 0;
for (int i = 0; i <= n; i++) {
long long coeff = ((i & 1) ? -1 : 1) * binomial(n, i);
not_win += coeff * binomial(k - 10 * i + n - 1, n - 1);
}
// 计算获胜概率
double win_prob = 1.0 - (double)not_win / pow(10, n);
cout << win_prob << endl;
return 0;
}
// 计算组合数 C(n, m)
long long binomial(int n, int m) {
long long res = 1;
for (int i = 1; i <= m; i++) {
res = res * (n - i + 1) / i;
}
return res;
}
```
其中 `binomial` 函数用来计算组合数,采用了阶乘公式 $C(n, m) = n!/(m!(n-m)!)$ 的实现方式,但是为了避免溢出,使用了循环计算的方式,每次只乘一个数,并且在乘完后除以一个数,避免中间结果超过 `long long` 范围的问题。
主函数中计算不满足条件的抽卡方案数采用了容斥原理的方式,先计算选了 $i$ 组卡牌的方案数 $\binom{n}{i}$,再计算在选了 $i$ 组卡牌的前提下,剩下的 $n-i$ 组卡牌总点数不小于 $k-10i$ 的方案数 $\binom{k-10i+n-1}{n-1}$,乘起来之后加到 `not_win` 中。最后用总方案数 $10^n$ 减去 `not_win`,得到小明获胜的方案数,除以 $10^n$ 得到小明获胜的概率。
阅读全文