本节探讨两例:有趣的抽牌概率计算,其中单色的数字牌设计比较简单,而由多花色扑克组成的数字牌涉及编码的转换,其中设计较为复杂,也更具有吸引力;
涉及到概率计算,必须统计事件的总体数与满足指定条件事件的个数,这是概率计算的基础;
抽数字牌
有n张数字牌,数字牌上分别标有整数1,2,3,……,n;
在这n张数字牌中同时抽取3张,记3张牌上的整数之和为素数的概率为p(n);
输入n(n>=10),计算并输出概率p(n)(精确到小数点后3位);
1.说明:
因任3张牌整数之和不小于6,可以排除唯一偶素数“2”;
(1)、试商法判别素数;
判别一个大于1的奇数i是否为素数,最简单的是根据素数的定义应用试商法完成,即用奇数(3~sqrt(i))进行试商判别;
为方便素数检测,设置数组q[i],对3n以内的整数i通过试商法给q[i]赋值:若i为素数,q[i]=1;否则q[i]=0;
(2)、枚举循环设计;
注意到任取3张牌即所得3个数不能相同。因而设置的i,j,k三重枚举循环的取值范围分别为:i(1~n-2),j(i+1~n-1),k(j+1~n);
这样的枚举循环设置,确保每不同的三张一组抽取,既无遗漏,也没有重复,这一点很重要,如果枚举循环设置不精准,出现遗漏或重复,会直接导致统计结果错误;
设s为从n张中取3张的总数,显然有:
- s=(3)C(n)=(n(n-1)(n-2))/6;
在内循环中通过w++统计所有不同的抽牌次数,并对取得的3个数应用q[i+j+k]=1判定3个数之和是否为素数,若是素数则通过m++统计和为素数的抽取次数;
(3)、计算概率;
循环结束后,比较w与s,若w!=s,说明循环设置出错,退出程序;
只有当w=s时,才计算并输出概率值p=m/w;
2.程序设计:
#include<stdio.h>
#include<math.h>
int main()
{
int i,j,k,n,t,z,q[3000];
long m,s,w;
double p;
printf("请输入牌的张数n(n<1000):");
scanf("%d",&n);
for(i=1;i<=3*n;i++)
q[i]=0;
for(i=3;i<=3*n;i=i+2)
{
t=1;
z=(int)sqrt(i);
for(j=3;j<=z;j=j+2)
if(i%j==0)
{
t=0;
break;
}
if(t==1) /*奇数i为素数时标记q[i]=1*/
q[i]=1;
}
m=w=0;
for(i=1;i<=n-2;i++) /*三重循环枚举抽牌*/
for(j=i+1;j<=n-1;j++)
for(k=j+1;k<=n;k