进球数
题目描述
中超继续进行,广州恒大和北京国安马上开赛了,比赛持续90分钟,为了分析方便,我们把5分钟作为一个时间片,那么比赛会进行18个时间片。在每一个时间片内,恒大踢进1球的概率百分比都是A%,国安踢进1球的概率都是B%。当比赛结束后,两支球队当中,至少有一支球队的进球数是质数的概率是多少?
输入格式
第一行,一个整数R,表示有R组测试数据。1 <= R <= 10。
每组测试数据格式:
第一行,A和B。 0 <= A <= 100, 0 <= B <= 100。
输出格式
共R行,每行一个实数,表示概率。
输入样例
3
50 50
100 100
12 89
输出样例
0.5265618908306351
0.0
0.6772047168840167
解题思路
题目大意:在18个时间片段内至少有一支球队的进球数是质数的概率是多少?
根据题意,简化一下问题,我们先单独考虑一支球队进球数是质数的概率。
如果一支球队的进球数为质数,那么这支队的进球数只能是2、3、5、7、11、13、17,继续简化问题,这支球队进球数为2,那么球队在18个时间片段内进2球的情况如下:
情况\时间片段 | 1 | 2 | 3 | 4 | 5 | 6 | …… | 17 | 18 |
---|---|---|---|---|---|---|---|---|---|
1 | √ √ √ | √ √ √ | × × × | × × × | × × × | × × × | × × × | × × × | × × × |
2 | √ √ √ | × × × | √ √ √ | × × × | × × × | × × × | × × × | × × × | × × × |
… … …… …… | … … …… …… | … … …… …… | … … …… …… | … … …… …… | … … …… …… | … … …… …… | … … …… …… | … … …… …… | … … …… …… |
18 | × × × | × × × | × × × | × × × | × × × | × × × | × × × | √ √ √ | √ √ √ |
哇!这个表的规模也太大了吧!
这样的情况有多少种呢?能不能通过计算将它算出来呢?仔细观察,我们就可以发现,这不就是组合数嘛!这就相当于从18个小球中选2个: C 18 2 C^{2}_{18} C182
在这18个时间片段中,只有2个时间片段进球,其他时间片段不能进球的情况下才符合当前题意,而这种情况又有 C 18 2 C^{2}_{18} C182种,所以设进球概率为 P ( g o a l ) P(goal) P(goal),球队在18个时间片段内进2球这种情况的概率是: C 18 2 × P ( g o a l ) 2 × ( 1 − P ( g o a l ) ) 16 C^{2}_{18}\times P(goal)^2 \times(1-P(goal))^{16} C182×P(goal)2×(1−P(goal))16
由此可知,进球数 i i i相对应的组合数是 C 18 i C^{i}_{18} C18i,概率算法也与上述相同: C 18 i × P ( g o a l ) i × ( 1 − P ( g o a l ) ) 18 − i C^{i}_{18}\times P(goal)^i \times(1-P(goal))^{18-i} C18i×P(goal)i×(1−P(goal))18−i(组合数可用杨辉三角预处理)。
现在,我们回归到原题,求至少有一支球队的进球数为质数的概率,先分类讨论一下:
- 恒大进球数为质数,国安进球数为非质数
- 恒大进球数为非质数,国安进球为质数
- 恒大进球数为质数,国安进球数为质数
将以上三种情况的概率求出来相加,就是答案了。但是,除此之外还有一种更简单的方法。
至少有一支球队的进球数为质数的概率=1-两支球队进球数都是非质数的概率
这样算就方便多了。
代码:
#include<iostream>
#include<fstream>
#include<algorithm>
#include<iomanip>
using namespace std;
int R,A,B;
long long C[25][25];
int composite[25]={0,1,4,6,8,9,10,12,14,15,16,18};//合数集合
double hd[25],ga[25],temp1,temp2,ans;
void init()
{
for(int i=0;i<=18;i++)
{
C[i][0]=1;
C[i][i]=1;
}
for(int i=1;i<=18;i++)
for(int j=1;j<i;j++)
C[i][j]=C[i-1][j-1]+C[i-1][j];
}
int main()
{
freopen("1265.in","r",stdin);
freopen("1265.out","w",stdout);
init();
cin>>R;
for(int r=1;r<=R;r++)
{
ans=0;
cin>>A>>B;
for(int i=0;i<=18;i++)
{
temp1=temp2=1;
for(int j=1;j<=i;j++)
temp1*=(double(A)*0.01);
for(int j=1;j<=18-i;j++)
temp2*=(1.00-double(A)*0.01);
hd[i]=double(C[18][i])*temp1*temp2;//恒大
temp1=temp2=1;
for(int j=1;j<=i;j++)
temp1*=(double(B)*0.01);
for(int j=1;j<=18-i;j++)
temp2*=(1.00-double(B)*0.01);
ga[i]=double(C[18][i])*temp1*temp2;//国安
}
for(int i=0;i<=11;i++)
for(int j=0;j<=11;j++)
ans+=hd[composite[i]]*ga[composite[j]];
ans=1.00-ans;
cout<<fixed<<setprecision(7)<<ans<<endl;
}
return 0;
}