题目描述:
足球比赛具有一定程度的偶然性,弱队也有战胜强队的可能。
假设有甲、乙、丙、丁四个球队。根据他们过去比赛的成绩,得出每个队与另一个队对阵时取胜的概率表:
甲 乙 丙 丁
甲 - 0.1 0.3 0.5
乙 0.9 - 0.7 0.4
丙 0.7 0.3 - 0.2
丁 0.5 0.6 0.8 -
数据含义:甲对乙的取胜概率为0.1,丙对乙的胜率为0.3,...
现在要举行一次锦标赛。双方抽签,分两个组比,获胜的两个队再争夺冠军。(参见【1.jpg】)
请你进行10万次模拟,计算出甲队夺冠的概率。
题目分析:
这个题目是通过多次试验的结果出现的频率,来模拟事件发生的概率;
比赛的分组一共有3种情况:
1. 甲乙一组,丙丁一组
2. 甲丙一组,乙丁一组
3. 甲丁一组,乙丙一组
其中,每一种情况,甲都可能获胜,也就有相应的获胜概率;
理想状态下,这三种情况,发生的概率是一样的也就是1/3;
我们可以由此得到一个理想状态下的甲获胜的概率,
我们将概率表定义为一个4×4的数组,则:
p1 = 1.0/3 * a[0][1] *(a[2][3] * a[0][2] + a[3][2] * a[0][3]);
p2 = 1.0/3 * a[0][2]*(a[1][3] * a[0][1] + a[3][1] * a[0][3]);
p3 = 1.0/3 * a[0][3]*(a[1][2] * a[0][1] + a[2][1] * a[0][2]);
p = p1+p2+p3 = 0.076
所以我们通过10万次模拟的结果应该在0.076附近
程序代码:
#include<iostream> #include<cstdlib> #include<ctime> using namespace std; double a[4][4]={{1,0.1,0.3,0.5},{0.9,1,0.7,0.4}, {0.7,0.3,1,0.2},{0.5,0.6,0.8,1}}; double fun2(double p1,int m,int n)//另一组比赛和第二轮比赛结果 { double p2 = a[m][n]; double p3 = a[0][m]; double t2 = a[n][m]; double t3 = a[0][n]; double p = p1*(p2*p3+t2*t3); return p; } double fun1(int n) { double p1 = a[0][n];//第一次比赛,甲获胜的概率 switch(n) { case 1: return fun2(p1,2,3);break; case 2: return fun2(p1,1,3);break; case 3: return fun2(p1,1,2);break; } } int main() { srand(time(0));//改变程序运行时随机数的值 int num = 100000; double sum =0; for(int i=0;i<num;i++) { sum += fun1(rand()%3+1); } cout<<sum/num<<endl; }
原文:http://blog.csdn.net/qsyzb/article/details/19213015