2012蓝桥杯【初赛试题】 夺冠概率

时间:2021-05-03 09:47:07

题目描述:

    足球比赛具有一定程度的偶然性,弱队也有战胜强队的可能。
    假设有甲、乙、丙、丁四个球队。根据他们过去比赛的成绩,得出每个队与另一个队对阵时取胜的概率表:


    甲  乙  丙  丁   
甲   -  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;
}

因为是概率事件,程序每次输出的结果都不一样,但都在0.076左右

第二遍做的时候,做了一些简化:

#include<iostream>
#include<ctime>
#include<cstdlib>
using namespace std;
int main()
{
float a[4][4]={0,0.1,0.3,0.5,0.9,0,0.7,0.4,0.7,0.3,0,0.2,0.5,0.6,0.8,0};
float p[3];
//甲乙——丙丁
p[0]=a[0][1]*(a[2][3]*a[0][2]+a[3][2]*a[0][3]);
//甲丙——乙丁
p[1]=a[0][2]*(a[1][3]*a[0][1]+a[3][1]*a[0][3]);
//甲丁——乙丙
p[2]=a[0][3]*(a[1][2]*a[0][1]+a[2][1]*a[0][2]);
srand(time(0));
float sum=0;
for(int i=0;i<10000;i++)
{
int r = rand()%3;
sum += p[r];
}
float pi = sum/10000;
cout<<pi<<endl;
}