題目是這樣的:編程
有三扇門,其中一扇門裏有獎品,三選一,你選擇其中一扇門以後,主持人先不揭曉答案,而是從另外兩扇門中排除掉一個沒有獎品的門,如今主持人問你,要不要換個門,請問你換仍是不換?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); }
實踐出真理,歡迎你們批評指正。