假设你在进行一个游戏节目。现有三扇门供你选择:一扇门后面是一辆轿车,另两扇门后面各是一头山羊。你当然更想得到轿车,但你却无法看到门后面的真实情况。主持人先让你做第一次选择。在你选择了一扇门后, 知道其余两扇门后面是什么的主持人,打开了另一扇门给你看:那里有一头山羊。现在主持人告诉你,你还有一次选择的机会。那么,你是坚持第一次的选择不变呢,还是改变第一次的选择?
让我们通过程序来模拟这个游戏,并计算不同选择对应的赢车概率:
#include<stdio.h>
#include<stdlib.h>
//下面是模拟函数,在main函数中每调用一次该函数,代表你做出了一次选择。
//以choice作为参数:choice为1,表示坚持第一次选择;choice为2,表示做出第二次选择。
int simulate(int choice)
{
//门的编号为0、1、2,下面的rand()用于随机地产生门号。
int doorBeforeCar = rand() % 3; //随机生成车所在的门号。
int doorFirstChoose = rand() % 3; //第一次做出的选择。
//主持人打开了一扇门,门后是羊。
int doorOpenedByHost; //主持人打开的门。
do
{
doorOpenedByHost = rand() % 3;
}
//因为主持人打开的门后面是羊不是车,所以doorOpenedByHost != doorBeforeCar
//因为主持人打开的不是你选择的门,所以doorOpenedByHost != doorFirstChoose
//直到doorOpenedByHost != doorBeforeCar 且 doorOpenedByHost != doorFirstChoose时,
//结束循环,因为这时doorOpenedByHost的值才是我们需要的。
while(doorOpenedByHost == doorBeforeCar || doorOpenedByHost == doorFirstChoose);
//因为门号为0、1、2,所以3扇门的门号之和3。
const int sumOfAllDoorNumbers = 3; //门号之和。
//第一次选的是doorFirstChoose,主持人打开的是doorOpenedByHost,所以第二次选择的
//是这两扇门之外的第三扇门。
//doorSecondChoose:第二次选择的门号。
int doorSecondChoose = sumOfAllDoorNumbers - doorFirstChoose - doorOpenedByHost;
if(choice == 1) //坚持第一次选择。
{
if(doorFirstChoose == doorBeforeCar)
return 1; //赢车
else
return 0; //没赢车
}
if(choice == 2) //做出第二次选择。
{
if(doorSecondChoose == doorBeforeCar)
return 1; //赢车
else
return 0; //没赢车
}
return 0; //choice的值除了1和2以外,其他都无效:赢车概率为0!
}
int main()
{
printf("If you stick to your choice, please enter 1.\n\n");
printf("If you change your mind, please enter 2.\n\n");
printf("Please make your choice: ");
int choice; //你的选择。
scanf("%d", &choice);
const int sumOfSimulations = 1000000; //游戏模拟的总次数。
int sumOfWinningCar = 0; //赢车总次数。
for(int i = 0; i < sumOfSimulations; i++)
{
sumOfWinningCar += simulate(choice);
}
double probabilityOfWinningCar = 1.0 * sumOfWinningCar / sumOfSimulations; //赢车概率。
printf("\nThe probability of winnig the car is: %lf\n", probabilityOfWinningCar);
return 0;
}
当输入1时,运行结果为:
当输入2时,运行结果为:
当输入其他数字时(无效,如3),运行结果为: