九张牌,一开始都是反面,每次随机抽取三张更改牌面正反,下一次抽取在此次基础之上,直到所有牌面均为正时停止。求抽取次数的期望。并计算在两百次以内抽取完毕的概率。
通过二进制位有三个1的随机数迭代异或,实现连续翻牌的效果。因为二进制中1的位数为3的情况一共只有84种,因此可以先利用一个三层循环将其存储于s[84]中,可以排序验证一下。
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int s[84]={0};
int cmp(const void *a,const void *b){
return *(int*)a-*(int*)b;}
int produce_random(void){
int n=rand()&511;
return n;
}
int randni(void){
int n=rand()%84;
return n;}
int expbi(const int n){
int m=1<<n;
return m;}
int main(int argc, char** argv){
int i=0,j,k,l;
int a,b,c;
int v=1000000;
for(j=0;j<7;j++){
for(k=j+1;k<8;k++){
for(l=k+1;l<9;l++){
s[i++]=expbi(j)+expbi(k)+expbi(l);
}
}
}
float sum=0.0;
//qsort(s,84,sizeof(int),cmp);
srand((unsigned int)time(NULL));
for(i=0;i<v;i++){
a=0;
for(k=0;k<100000;k++){
b=randni();
b=s[b];
a=a^b;
if(a==511)break;
}
// printf("%d\n",k);
sum+=k;
// if(k<200)
//sum+=1;
}
sum/=v;
printf("%f",sum);
/* for(i=0;i<84;i++)
printf("%d\n",s[i]);*/
return 0;
}
循环一百万次计算期望均值的结果
大概是517次左右
下面是200次就成功的概率