蓝桥杯-古代赌局问题
问题描述:
俗话说:十赌九输。因为大多数赌局的背后都藏有阴谋。
不过也不尽然,有些赌局背后藏有的是:“阳谋”。
有一种赌局是这样的:桌子上放六个匣子,编号是1至6。
多位参与者(以下称玩家)可以把任意数量的钱押在某个编号的匣子上。
所有玩家都下注后,庄家同时掷出3个骰子(骰子上的数字都是1至6)。
输赢规则如下:
1.若只有1个骰子上的数字与玩家所押注的匣子号相同,则玩家拿回自己的押注,庄家按他押注的数目赔付(即1比1的赔率)。
2.若2个骰子上的数字与玩家所押注的匣子号相同,则玩家拿回自己的押注,庄家按他押注的数目的2倍赔付(即1比2的赔率)。
3.若3个骰子上的数字都与玩家押注的匣子号相同,则玩家拿回自己的押注,庄家按他押注的数目的10倍赔付(即1比10的赔率)。
乍一看起来,好像规则对玩家有利,庄家吃亏。但经过大量实战,会发现局面很难说,于是怀疑是否庄家做了手脚,庄家则十分爽快地说:可以由玩家提供骰子,甚至也可以由玩家来投掷骰子。
你的任务是:通过编程模拟该过程。模拟50万次,假定只有1个玩家,他每次的押注都是1元钱,其押注的匣子号是随机的。再假定庄家有足够的资金用于赔付。最后计算出庄家的盈率(庄家盈利金额/押注总金额)。
问题分析:
此题是一道简单的概率题,在蓝桥杯比赛中这种题属于送分,但对于初次接触此题的同学来说,仍有一些要注意的地方,比如说求这个1-6的随机数,C++与C是不一样的函数,这两个函数的原理也不一样。
C++中rand()函数,是返回0-RAND_MAX之间均匀分布的伪随机整数。 RAND_MAX必须至少为32767。rand()函数不接受参数,默认以1为种子(即起始值)。
C中random()函数,功能:随机数发生器 用法:intrandom(intnum); 根据提供的num,随机产生0-num-1范围的数据。
产生一定范围随机数的通用表示公式
1)要取得[a,b)的随机整数,使用(rand() % (b-a))+ a;
2)要取得[a,b]的随机整数,使用(rand() % (b-a+1))+ a;
3)要取得(a,b]的随机整数,使用(rand() % (b-a))+ a + 1;
4)通用公式:a + rand() % n;其中的a是起始值,n是整数的范围。
5)要取得a到b之间的随机整数,另一种表示:a + (int)b * rand() / (RAND_MAX + 1)。
6)要取得0~1之间的浮点数,可以使用rand() / double(RAND_MAX)。
代码描述:
1 #include<iostream> 2 #include<cstdlib>//一定要加c这个字母,不要把C语言的头文件与C++中的弄混淆了 3 using namespace std; 4 int f(); 5 double moni(int n); 6 int main(){ 7 int n=500*1000;//定义50万,亮点 8 cout<<moni(n)/n; 9 return 0; 10 } 11 int f(){ 12 int a,b,c,p,i=0; 13 /*模拟3次骰子,注意求小数的随机数与求1-10整数的随机数,使用int将其强制转换为整型*/ 14 a=(int)(rand()/(RAND_MAX+0.0)*6)+1;//RAND_MAX 15 b=(int)(rand()/(RAND_MAX+0.0)*6)+1; 16 c=(int)(rand()/(RAND_MAX+0.0)*6)+1; 17 /*模拟此人此次押注*/ 18 p=(int)rand()/(RAND_MAX+0.0)*6+1; 19 //下面统计压中次数是一个亮点 20 if(a==p) i++; 21 if(b==p) i++; 22 if(c==p) i++; 23 if(i==3) return -10; 24 if(i==2) return -2; 25 if(i==1) return -1; 26 return 1; 27 } 28 double moni(int n){ 29 double sum=0; 30 for(int i=0;i<n;i++)//模拟n次 31 sum+=f(); 32 return sum; 33 }