关于博饼概率

写在前面

中秋要到了,班级举办博饼活动。今年 rp 尽失,最大只摇到一秀(这也算一种运气吧)。悲愤交加之余,遂作本文。

正文

为了防止有些同学不了解博饼规则,贴张图。有些地方和下面的表述不同,但不影响大意。

模拟结果

电脑模拟 10810^8108 次后的结果。

科举出现次数概率
状元插金花324930.032493%
六杯红21420.002142%
六杯黑107480.010748%
五红642340.064234%
五子登科3218860.321886%
四红7700460.770046%
对堂15445321.544532%
三红53593675.359367%
四进40173714.017371%
二举1993769819.937698%
一秀3729461837.294618%
3064486530.644865%

大家可以研究一下它们出现的数学概率,应该不会和这个概率相差太大。

更多的模拟结果

懒得做表格了

每次结果不会相差太大。

分析

总体来讲是符合预期的,但是也有几个意想不到的地方。

  1. 状元插金花的出现次数是六杯红的 16 倍左右,虽然它一般是最大的奖项。
  2. 三红的出现概率比四进大一些,同样的,它在博饼规则中通常比四进大一些。

总结

没想好怎么说,先鸽着吧。

测试程序

#include <iostream>
#include <algorithm>
#include <string>
#include <chrono>
#include <random>
#include <cstring>
#include <cstdio>

using namespace std;

const int N = 101;
int a[7],n,now,c = 1e8;
string name[N],temp;
mt19937 rd(chrono::system_clock::now().time_since_epoch().count());
int duitang,zhuangyuanchajinhua,liubeihong,liubeihei,wuhong,wuzidengke,sihong,sanhong,
sijin,erju,yixiu,None;

int main(){
	freopen("output.txt","w",stdout);
	while(c--){
		memset(a,0,sizeof a); 
		for(int i = 1;i <= 6;i++){
			int t = rd()%6 + 1;
			a[t]++;
		}
		if(all_of(a+1,a+7,
			[](int x){
				return x;
			}
		)){
			duitang++;
		}
		else if(any_of(a+1,a+7,
			[](int x){
				return x == 6;
			}
		)){
			if(a[4] == 6){
				liubeihong++;
			}
			else{
				liubeihei++;
			}
		}
		else if(a[4] == 4 && a[1] == 2){
			zhuangyuanchajinhua++;
		}
		else if(any_of(a+1,a+7,
			[](int x){
				return x == 5;
			}
		)){
			if(a[4] == 5){
				wuhong++;
			}
			else{
				wuzidengke++;
			}
		}
		else if(any_of(a+1,a+7,
			[](int x){
				return x == 4;
			}
		)){
			if(a[4] == 4){
				sihong++;
			}
			else{
				sijin++;
			}
		}
		else if(a[4] == 3){
			sanhong++;
		}
		else if(a[4] == 2){
			erju++;
		}
		else if(a[4] == 1){
			yixiu++;
		}
		else{
			None++;
		}
	}
	cout << "状元插金花:" << zhuangyuanchajinhua << '\n'
		 << "六杯红:" << liubeihong << '\n'
		 << "六杯黑:" << liubeihei << '\n'
		 << "五红:" << wuhong << '\n'
		 << "五子登科:" << wuzidengke << '\n'
		 << "四红:" << sihong << '\n'
		 << "对堂:" << duitang << '\n'
		 << "三红:" << sanhong << '\n'
		 << "四进:" << sijin << '\n'
		 << "二举:" << erju << '\n'
		 << "一秀:" << yixiu << '\n'
		 << "无:" << None; 

	return 0;
}

模拟博饼小游戏

大家可以用这个娱乐一下。

#include <iostream>
#include <algorithm>
#include <string>
#include <chrono>
#include <random>
#include <cstring>
#define duitang cout << "恭喜" << name[now] << "博得对堂!\n\n";continue;
#define zhuangyuanchajinhua cout << "恭喜" << name[now] << "博得状元插金花!\n\n";continue;
#define liubeihong cout << "恭喜" << name[now] << "博得六杯红!\n\n";continue;
#define liubeihei cout << "恭喜" << name[now] << "博得六杯黑!\n\n";continue;
#define wuhong cout << "恭喜" << name[now] << "博得五红!\n\n";continue;
#define wuzidengke cout << "恭喜" << name[now] << "博得五子登科!\n\n";continue;
#define sihong cout << "恭喜" << name[now] << "博得四红!\n\n";continue;
#define sanhong cout << "恭喜" << name[now] << "博得三红!\n\n";continue;
#define sijin cout << "恭喜" << name[now] << "博得四进!\n\n";continue;
#define erju cout << "恭喜" << name[now] << "博得二举!\n\n";continue;
#define yixiu cout << "恭喜" << name[now] << "博得一秀!\n\n";continue;

using namespace std;

const int N = 101;
int a[7],n,now;
string name[N],temp;
mt19937 rd(chrono::system_clock::now().time_since_epoch().count());

int main(){
	cout << "请输入参与博饼的人数(100人以内):"; 
	cin >> n;
	cout << "请依次输入参与博饼的人的名字,以回车间隔:\n";
	getline(cin,temp);
	for(int i = 1;i <= n;i++){
		getline(cin,name[i]);
	}
	while(true){
		if(now == n) now = 0;
		now++;
		memset(a,0,sizeof a);
		cout << "请" << name[now] << "掷骰子(按回车)";
		getline(cin,temp);
		cout << name[now] << "的结果为:\n";
		for(int i = 1;i <= 6;i++){
			int t = rd()%6 + 1;
			a[t]++;
			cout << t << ' ';
		}
		cout << '\n';
		if(all_of(a+1,a+7,
			[](int x){
				return x;
			}
		)){
			duitang
		}
		else if(any_of(a+1,a+7,
			[](int x){
				return x == 6;
			}
		)){
			if(a[4] == 6){
				liubeihong
			}
			else{
				liubeihei
			}
		}
		else if(a[4] == 4 && a[1] == 2){
			zhuangyuanchajinhua
		}
		else if(any_of(a+1,a+7,
			[](int x){
				return x == 5;
			}
		)){
			if(a[4] == 5){
				wuhong
			}
			else{
				wuzidengke
			}
		}
		else if(any_of(a+1,a+7,
			[](int x){
				return x == 4;
			}
		)){
			if(a[4] == 4){
				sihong
			}
			else{
				sijin
			}
		}
		else if(a[4] == 3){
			sanhong
		}
		else if(a[4] == 2){
			erju
		}
		else if(a[4] == 1){
			yixiu
		}
		else{
			cout << "再试试吧!\n\n";
		}
	}

	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值