一和有趣的问题,三选一

来源:互联网 发布:极光推送golang 编辑:程序博客网 时间:2024/06/03 20:14
 今天,和同事们聊到个有趣的问题:"有3扇门,1,2,3,其中有扇门有辆汽车,如果选中正确的那扇门,就可以获得汽车.首先,你可以选择一扇门,然后,主持人可以在另外两扇门中排出一扇错误的门,这个时候,你可以选择坚持已经选择的门,或者换另外一扇门".

比如说:
1 2 3
我选择1
主持人排出了3
还剩余1 2
我可以继续坚持选1,或者放弃,而改选2

起初,我认为的中奖概率为:
1      2      3
1/3  1/3   1/3

当主持人排出3后,中奖概率为:
1      2      3
1/2  1/2    0

但实际上这是错误的理解!我通过程序测试了上万次,正确的概率为:
1      2      3
1/3  2/3    0

代码如下

 

package openthedoor;import java.util.Random;import java.util.Scanner;/** * * @author Vicky.H * @email eclipser@163.com */public class OpenTheDoor {    // 记录猜对的次数    private static int win = 0;    // 记录玩家选择的门    private static int enter = 0;    private static Random random = new Random();    private static boolean doors[] = new boolean[3];    /**     * @param args the command line arguments     */    public static void main(String[] args) {        System.out.println("程序说明:\n输入1,2,3之间的数字代表一个门,每次将随机排列门中是否有宝马!\n共猜1000次,如果第一次就猜中,将不计算在10次内!");        run(1);        System.err.println("死脑筋,坚持1不变:1000次猜对:" + win + ",概率为:" + win / 1000.0);        System.out.println("------------------------");        win = 0;        run2(1);        System.err.println("开始选1,系统筛选后,选择另外一个数:1000次猜对:" + win + ",概率为:" + win / 1000.0);    }    /**     * 坚持选择一个数     * @param enter      */    private static void run(int enter) {        for (int i = 0; i < 1000; i++) {            initDoors();            System.out.println(">>>第" + i + "次测试开始:");            doors[random.nextInt(3)] = true;            try {                // enter = new Scanner(System.in).nextInt();                if (enter < 1 || enter > 3) {                    System.out.println("请输入1,2,3之中的数字!");                    i--;                    continue;                }            } catch (Exception e) {                System.out.println("请输入1,2,3之中的数字!");                i--;                continue;            }                        int falseDoor = getFalseDoor(enter - 1); // 这条语句已经将概率做了改变!!!!!!!!!!                        System.out.println("系统排出一个错误的门:" + falseDoor + " !请输入另外一个不为:" + falseDoor + "门");            try {                // enter = new Scanner(System.in).nextInt();                if (enter < 1 || enter > 3 || enter == falseDoor) {                    System.out.println("请输入1,2,3之中的数字!");                    i--;                    continue;                }            } catch (Exception e) {                System.out.println("请输入1,2,3之中的数字!");                i--;                continue;            }            if (doors[enter - 1]) { // 第二次输入                win++;                System.out.println("第二次猜中,共猜对:" + win + "次!!!");            } else {                System.out.println("第二次未能猜对!");            }            System.out.println(doors[0] + " ," + doors[1] + " ," + doors[2]);        }    }        /**     * 选择另外个数     * @param enter      */    private static void run2(int enter) {        for (int i = 0; i < 1000; i++) {            initDoors();            System.out.println(">>>第" + i + "次测试开始:");            doors[random.nextInt(3)] = true;            try {                // enter = new Scanner(System.in).nextInt();                if (enter < 1 || enter > 3) {                    System.out.println("请输入1,2,3之中的数字!");                    i--;                    continue;                }            } catch (Exception e) {                System.out.println("请输入1,2,3之中的数字!");                i--;                continue;            }                        int falseDoor = getFalseDoor(enter - 1); // 这条语句已经将概率做了改变!!!!!!!!!!                        System.out.println("系统排出一个错误的门:" + falseDoor + " !请输入另外一个不为:" + falseDoor + "门");            // 选择另外一个数            int tmp = random.nextInt(3) + 1;            while(enter == tmp || enter == falseDoor){                tmp = random.nextInt(3) + 1;            }            enter = tmp;                        try {                // enter = new Scanner(System.in).nextInt();                if (enter < 1 || enter > 3 || enter == falseDoor) {                    System.out.println("请输入1,2,3之中的数字!");                    i--;                    continue;                }            } catch (Exception e) {                System.out.println("请输入1,2,3之中的数字!");                i--;                continue;            }            if (doors[enter - 1]) { // 第二次输入                win++;                System.out.println("第二次猜中,共猜对:" + win + "次!!!");            } else {                System.out.println("第二次未能猜对!");            }            System.out.println(doors[0] + " ," + doors[1] + " ," + doors[2]);        }    }    private static void initDoors() {        doors[0] = false;        doors[1] = false;        doors[2] = false;    }    private static int getFalseDoor(int enter) {        int i = random.nextInt(3);        while (i == enter) {            i = random.nextInt(3);        }        if (!doors[i]) {            return i + 1;        } else {            return getFalseDoor(enter);        }    }}

死脑筋,坚持1不变:1000次猜对:362,概率为:0.362
开始选1,系统筛选后,选择另外一个数:1000次猜对:655,概率为:0.655

 

死脑筋,坚持1不变:1000次猜对:341,概率为:0.341

开始选1,系统筛选后,选择另外一个数:1000次猜对:656,概率为:0.656

 

原创粉丝点击