一和有趣的问题,三选一

 今天,和同事们聊到个有趣的问题:"有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

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值