代码实现 C++ 小明参加一个比赛,规则是:每组卡牌有十张且点数为 1 到 10,现有 n 组卡牌,选手要在 n 组卡牌中,每组抽取一张,共抽 n 张;若 n 张卡牌的总点数大于 k 则小明获胜,求小明获胜的概率有多大?
时间: 2023-12-15 15:05:47 浏览: 68
下面是使用 C++ 的迭代器实现的代码,思路与前面的递归版类似,只是使用了迭代器来遍历每一组卡牌。
```c++
#include <bits/stdc++.h>
using namespace std;
int n, k, win, sum;
vector<int> cards;
void dfs(vector<int>::iterator cur) {
if (cur == cards.end()) {
if (sum > k) {
win++;
}
return;
}
for (int i = 1; i <= 10; i++) {
sum += *cur = i;
dfs(cur + 1);
sum -= *cur;
}
}
int main() {
cin >> n >> k;
cards.resize(n);
dfs(cards.begin());
double ans = (double)win / pow(n, n);
cout << ans << endl;
return 0;
}
```
代码中使用了一个迭代器 cur 来指向当前正在处理的卡牌组,初始值为 cards.begin();在 dfs 函数中,使用 *cur 访问当前卡牌组选出的卡牌点数。其他部分与递归版代码基本相同。
相关问题
c++代码实现 小明参加一个比赛,规则是:每组卡牌有十张且点数为 1 到 10,现有 n 组卡牌,选手要在 n 组卡牌中,每组抽取一张,共抽 n 张;若 n 张卡牌的总点数大于 k 则小明获胜,求小明获胜的概率有多大?
请看下面的代码实现:
```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$ 得到小明获胜的概率。
代码实现 小明参加一个比赛,规则是:每组卡牌有十张且点数为 1 到 10,现有 n 组卡牌,选手要在 n 组卡牌中,每组抽取一张,共抽 n 张;若 n 张卡牌的总点数大于 k 则小明获胜,求小明获胜的概率有多大?
这是一个简单的计算概率问题,可以使用暴力枚举的方法解决。具体步骤如下:
1. 输入卡牌组数 n 和总点数 k。
2. 枚举每一组卡牌,使用递归的方式从每组卡牌中选出一张卡牌,直到选出 n 张卡牌。
3. 在递归的过程中,记录已选卡牌的总点数 sum,如果 sum 大于 k,则统计一次获胜次数 win。
4. 统计获胜概率,即 win/n^n,输出结果。
下面是代码实现:
```c++
#include <bits/stdc++.h>
using namespace std;
int n, k, win, sum;
vector<int> cards;
void dfs(int cur) {
if (cur == n) {
if (sum > k) {
win++;
}
return;
}
for (int i = 1; i <= 10; i++) {
sum += cards[cur] = i;
dfs(cur + 1);
sum -= cards[cur];
}
}
int main() {
cin >> n >> k;
cards.resize(n);
dfs(0);
double ans = (double)win / pow(n, n);
cout << ans << endl;
return 0;
}
```
代码中使用了一个全局变量 cards 来保存每组卡牌选出的卡牌点数,避免了传参和回溯的麻烦。在 dfs 函数中,使用 cur 参数表示当前已选卡牌组数,从 0 开始递归;使用 i 枚举当前卡牌组选出的卡牌点数,将其保存到 cards[cur] 中,并更新 sum;在递归结束后,将 cards[cur] 重置为 0,sum 减去该卡牌点数,回溯到上一层递归。
最后,统计获胜概率并输出结果。
阅读全文