思考:有三扇門,其中一扇門裏有獎品,三選一,你選擇其中一扇門以後,主持人先不揭曉答案,而是從另外兩扇門中排除掉一個沒有獎品的門,如今主持人問你,要不要換個門,請問你換仍是不換?

題目是這樣的:編程

有三扇門,其中一扇門裏有獎品,三選一,你選擇其中一扇門以後,主持人先不揭曉答案,而是從另外兩扇門中排除掉一個沒有獎品的門,如今主持人問你,要不要換個門,請問你換仍是不換?dom

起初我覺得換與不換都是二分之一的機率,後來,我寫了一個程序來證明,發現仍是要換的,換是三分之二的中獎機率,不換是三分之一的中獎機率,差不少。編程語言

 

直接看個人測試結果吧:函數

這是C語言編寫的程序,測試的結果。(要解答這個題目,其實和什麼編程語言無關)測試

 

這是C#語言編寫的程序,測試的結果。(要解答這個題目,其實和什麼編程語言無關)ui

 

這是Java語言編寫的程序,測試的結果。(要解答這個題目,其實和什麼編程語言無關)spa

 

屢次測試的結果顯示,若是換門的話選中目標門的機率大多了。code

固然,採樣20次,有點少,那咱們就來進行1000次測試,看看結果又如何。orm

當測試1000次時,就能夠明顯的發現,不換門的中獎機率是3/1,而換門的中獎機率是3/2,差異很大。blog

 

如下是C、C#、Java三種不一樣語言編寫的測試代碼:

 

1、C語言測試代碼

  1 #include <stdio.h>
  2 #include <time.h>
  3 #include <stdlib.h>
  4 
  5 //有三扇門,其中一扇門裏有獎品,三選一,你選擇其中一扇門以後
  6 //主持人先不揭曉答案,而是從另外兩扇門中排除掉一個沒有獎品的門
  7 //如今主持人問你,要不要換個門,請問你換仍是不換?
  8  9 
 10 //測試(總次數, 換門)
 11 void test(int max, int change);
 12 
 13 //入口函數
 14 void main()
 15 {
 16     //各自測試的次數
 17     int count = 20;
 18 
 19     //初始化隨機種子
 20     srand((unsigned)time(NULL));
 21 
 22     //不換門測試
 23     printf("不換門測試:\n");
 24     test(count, 0);
 25 
 26     //換門測試
 27     printf("換門測試:\n");
 28     test(count, 1);
 29 }
 30 
 31 //測試(總次數, 換門)
 32 void test(int max, int change)
 33 {
 34 
 35     //max    次數:測試的總次數
 36     //change 換門: 0不換  1換門
 37 
 38     int i;        //循環因子
 39     int m;        //目標:本次中獎的目標數字
 40     int c;        //初選:本次選手初次選擇的數字
 41     int x;        //選擇:本次選手最終選擇的數字
 42     int p;        //排除:主持人排除掉沒獎的數字
 43     int z = 0;    //中獎:中獎的總次數
 44 
 45     //循環屢次模擬換門測試
 46     for (i=0; i<max; i++)
 47     {
 48         m = rand()%3; //目標:本次中獎的目標數字
 49         c = rand()%3; //初選:本次選手初次選擇的數字
 50         
 51         //求出主持人要排除的數字
 52         if(m==c)
 53         {
 54             //選手選擇了一個有獎品的,主持人從另外兩個沒獎品當中隨機排除掉一下
 55             p = rand()%2;  //產生  false or true
 56             switch(c)
 57             {
 58             case 0:  //要排除的是:2 or 1
 59                 p = p?2:1;
 60                 break;
 61             case 1:  //要排除的是:2 or 0
 62                 p = p?2:0;
 63                 break;
 64             case 2:  //要排除的是:1 or 0
 65                 p = p?1:0;
 66                 break;;
 67             }
 68         }
 69         else
 70         {
 71             //選手選擇了一個沒獎品的,主持人排除另外一個沒獎品的
 72             //3-(m+c) = p
 73             //3-(0+1) = 2
 74             //3-(0+2) = 1
 75             //3-(1+2) = 0
 76             p = 3-(m+c);            
 77         }
 78         
 79         //決定終選
 80         if(change)
 81         {//換門
 82             //x=3-(p+c)
 83             //x=3-(0+1) = 2
 84             //x=3-(0+2) = 1
 85             //x=3-(1+2) = 0
 86             x = 3-(p+c);  //換個門
 87         }
 88         else
 89         {//不換門
 90             x = c;  //最終選擇和初次選擇同樣
 91         }
 92         
 93         //結果
 94         printf("第%02d次  初選的是:%d, 目標是:%d, 排除的是:%d, 終選的是:%d", i+1, c, m, p, x);
 95         if(m==x)
 96         {
 97             //中獎了
 98             z++;
 99             printf("  (中獎了)\n");
100         }
101         else
102         {
103             //沒中獎
104             printf("\n");
105         }
106     }
107     //輸出結果
108     printf("進行%d次測試,中獎%d次。\n\n", max, z);
109 }

 

2、C# 測試代碼

using System;
using System.Collections.Generic;
using System.Text;

//有三扇門,其中一扇門裏有獎品,三選一,你選擇其中一扇門以後
//主持人先不揭曉答案,而是從另外兩扇門中排除掉一個沒有獎品的門
//如今主持人問你,要不要換個門,請問你換仍是不換?
//

namespace Test123
{
    class Program
    {
        //初始化隨機數生成器
        static Random random = new Random();

        //入口函數
        static void Main(string[] args)
        {
            //測試總次數
            int count = 20;
            //不換門測試
            Console.WriteLine("不換門測試:");
            test(count, false);
            //換門測試
            Console.WriteLine("換門測試:");
            test(count, true);
        }

        //測試(總次數, 換門)
        static void test(int max, bool change)
        {
            //max    次數:測試的總次數
            //change 換門: 0不換  1換門

            int i;        //循環因子
            int m;        //目標:本次中獎的目標數字
            int c;        //初選:本次選手初次選擇的數字
            int x;        //選擇:本次選手最終選擇的數字
            int p = 0;    //排除:主持人排除掉沒獎的數字
            int z = 0;    //中獎:中獎的總次數
            bool b;       //臨時布爾類型變量

            //循環屢次模擬換門測試
            z = 0; //重置中獎次數
            for (i = 0; i < max; i++)
            {
                m = random.Next(3); //目標:本次中獎的目標數字
                c = random.Next(3); //初選:本次選手初次選擇的數字

                //求出主持人要排除的數字
                if (m == c)
                {
                    //選手選擇了一個有獎品的,主持人從另外兩個沒獎品當中隨機排除掉一下
                    b = random.Next(2) == 1;  //產生  false or true
                    switch (c)
                    {
                        case 0:  //要排除的是:2 or 1
                            p = b ? 2 : 1;
                            break;
                        case 1:  //要排除的是:2 or 0
                            p = b ? 2 : 0;
                            break;
                        case 2:  //要排除的是:1 or 0
                            p = b ? 1 : 0;
                            break;
                    }
                }
                else
                {
                    //選手選擇了一個沒獎品的,主持人排除另外一個沒獎品的
                    //3-(m+c) = p
                    //3-(0+1) = 2
                    //3-(0+2) = 1
                    //3-(1+2) = 0
                    p = 3 - (m + c);
                }

                //決定終選
                if (change)
                {//換門
                    //x=3 - (p + c)
                    //x=3 - (0 + 1) = 2
                    //x=3 - (0 + 2) = 1
                    //x=3 - (1 + 2) = 0
                    x = 3 - (p + c);  //換個門
                }
                else
                {//不換門
                    x = c;  //最終選擇和初次選擇同樣
                }

                //結果
                Console.Write("第{0:00}次  初選的是:{1}, 目標是:{2}, 排除的是:{3}, 終選的是:{4}", i + 1, c, m, p, x);
                if (m == x)
                {
                    //中獎了
                    z++;
                    Console.Write("  (中獎了)\n");
                }
                else
                {
                    //沒中獎
                    Console.Write("\n");
                }
            }
            //輸出結果
            Console.Write("進行{0}次測試,中獎{1}次。\n\n\n", max, z);
        }


    }
}

 

3、Java 測試代碼

package com.huarui.test;

//有三扇門,其中一扇門裏有獎品,三選一,你選擇其中一扇門以後
//主持人先不揭曉答案,而是從另外兩扇門中排除掉一個沒有獎品的門
//如今主持人問你,要不要換個門,請問你換仍是不換?
//
public class Test {
    
    public static void main(String[] args){
        
        //測試的總次數
        int count = 20;
        //不換門測試
        System.out.println("不換門測試:");
        test(count, false);
        //換門測試
        System.out.println("換門測試:");
        test(count, true);
        
    }
    
    //測試(總次數, 換門)
    static void test(int max, boolean change)
    {
        //max    次數:測試的總次數
        //change 換門: 0不換  1換門

        int i;        //循環因子
        int m;        //目標:本次中獎的目標數字
        int c;        //初選:本次選手初次選擇的數字
        int x;        //選擇:本次選手最終選擇的數字
        int p = 0;    //排除:主持人排除掉沒獎的數字
        int z = 0;    //中獎:中獎的總次數

        //循環屢次模擬換門測試
        z = 0; //重置中獎次數
        for (i = 0; i < max; i++)
        {
            m = (int)(Math.random()*3); //目標:本次中獎的目標數字
            c = (int)(Math.random()*3); //初選:本次選手初次選擇的數字

            //求出主持人要排除的數字
            if (m == c)
            {
                //選手選擇了一個有獎品的,主持人從另外兩個沒獎品當中隨機排除掉一下
                boolean b =  (int)(Math.random()*2) == 1;  //產生  false or true
                switch (c)
                {
                    case 0:  //要排除的是:2 or 1
                        p = b ? 2 : 1;
                        break;
                    case 1:  //要排除的是:2 or 0
                        p = b ? 2 : 0;
                        break;
                    case 2:  //要排除的是:1 or 0
                        p = b ? 1 : 0;
                        break;
                }
            }
            else
            {
                //選手選擇了一個沒獎品的,主持人排除另外一個沒獎品的
                //3-(m+c) = p
                //3-(0+1) = 2
                //3-(0+2) = 1
                //3-(1+2) = 0
                p = 3 - (m + c);
            }

            //決定終選
            if (change)
            {//換門
                //x=3 - (p + c)
                //x=3 - (0 + 1) = 2
                //x=3 - (0 + 2) = 1
                //x=3 - (1 + 2) = 0
                x = 3 - (p + c);  //換個門
            }
            else
            {//不換門
                x = c;  //最終選擇和初次選擇同樣
            }

            //結果
            //, i + 1, c, m, p, x
            
            System.out.format("第%02d次  初選的是:%d, 目標是:%d, 排除的是:%d, 終選的是:%d", i + 1, c, m, p, x);
            if (m == x)
            {
                //中獎了
                z++;
                System.out.print("  (中獎了)\n");
            }
            else
            {
                //沒中獎
                System.out.print("\n");
            }
        }
        //輸出結果
        System.out.format("進行%d次測試,中獎%d次。\n\n\n", max, z);
    }
}

 

4、另外,當須要進行1000次測試時,就不適合將每一次測試的結果都進行輸出了,代碼稍微改一下,將C語言的代碼發給你們看看

#include <stdio.h>
#include <time.h>
#include <stdlib.h>

//有三扇門,其中一扇門裏有獎品,三選一,你選擇其中一扇門以後
//主持人先不揭曉答案,而是從另外兩扇門中排除掉一個沒有獎品的門
//如今主持人問你,要不要換個門,請問你換仍是不換?
////測試(總次數, 換門)
void test(int max, int change);

//入口函數
void main()
{
    //各自測試的次數
    int i, count = 1000;

    //初始化隨機種子
    srand((unsigned)time(NULL));

    for(i=0;i<5;i++)
    {
        printf("================================\n");

        //不換門測試
        printf("不換門測試:\n");
        test(count, 0);

        //換門測試
        printf("換門測試:\n");
        test(count, 1);
    }
}

//測試(總次數, 換門)
void test(int max, int change)
{

    //max    次數:測試的總次數
    //change 換門: 0不換  1換門

    int i;        //循環因子
    int m;        //目標:本次中獎的目標數字
    int c;        //初選:本次選手初次選擇的數字
    int x;        //選擇:本次選手最終選擇的數字
    int p;        //排除:主持人排除掉沒獎的數字
    int z = 0;    //中獎:中獎的總次數

    //循環屢次模擬換門測試
    for (i=0; i<max; i++)
    {
        m = rand()%3; //目標:本次中獎的目標數字
        c = rand()%3; //初選:本次選手初次選擇的數字
        
        //求出主持人要排除的數字
        if(m==c)
        {
            //選手選擇了一個有獎品的,主持人從另外兩個沒獎品當中隨機排除掉一下
            p = rand()%2;  //產生  false or true
            switch(c)
            {
            case 0:  //要排除的是:2 or 1
                p = p?2:1;
                break;
            case 1:  //要排除的是:2 or 0
                p = p?2:0;
                break;
            case 2:  //要排除的是:1 or 0
                p = p?1:0;
                break;;
            }
        }
        else
        {
            //選手選擇了一個沒獎品的,主持人排除另外一個沒獎品的
            //3-(m+c) = p
            //3-(0+1) = 2
            //3-(0+2) = 1
            //3-(1+2) = 0
            p = 3-(m+c);            
        }
        
        //決定終選
        if(change)
        {//換門
            //x=3-(p+c)
            //x=3-(0+1) = 2
            //x=3-(0+2) = 1
            //x=3-(1+2) = 0
            x = 3-(p+c);  //換個門
        }
        else
        {//不換門
            x = c;  //最終選擇和初次選擇同樣
        }
        
        //結果
        //printf("第%02d次  初選的是:%d, 目標是:%d, 排除的是:%d, 終選的是:%d", i+1, c, m, p, x);
        if(m==x)
        {
            //中獎了
            z++;
            //printf("  (中獎了)\n");
        }
        else
        {
            //沒中獎
            //printf("\n");
        }
    }
    //輸出結果
    printf("進行%d次測試,中獎%d次。\n\n", max, z);
}

 

實踐出真理,歡迎你們批評指正。 

相關文章
相關標籤/搜索