思路:纯模拟
(轮流)--->set(轮流)--->game(同个人)--->point
(1):set要赢的条件为1.至少赢六局2.比对手多赢至少两局
(2):game要赢的条件为1.至少得四分2.比对手多得至少两分
(3):point时特殊考虑3:3
(4):game时特殊考虑5:5
PS.比赛的时候想了下思路,让队友敲的(1A),赛后自己又做了一遍,也是1A.....,这题的确不难,就是纯模拟、、、
CODE:
/*概率题*/
/*AC代码:64ms*/
#include <iostream>
#include <cstdio>
#include <memory.h>
#include <algorithm>
#include <cmath>
using namespace std;
int cas;
double pw1,pw2;//分别表示发球或不发球赢下这一point的概率
double gw1,gw2;//分别表示发球或不发球赢下这一game的概率
double sw1,sw2;//分别表示发球或不发球赢下这一set的概率
int C(int n,int m)
{
int i,j,res=1;
if(m==0||n==0) return 1;
for(i=1,j=n;i<=m;i++,j--)
res=res*j/i;
return res;
}
double get_g(double p)
{
double a,b,c,d;
a=C(3,3)*pow(p,4);b=C(4,1)*pow(p,4)*(1-p);
c=C(5,2)*pow(p,4)*pow((1-p),2);
d=C(6,3)*pow(p,3)*pow((1-p),3)*((p*p)/(p*p+(1-p)*(1-p)));
return a+b+c+d;
}
double get_s(double gw1,double gw2)
{
int i,j,k,x,y;
double res=0,temp;
x=3;y=2;
for(k=0;k<=4;k++)//6:0--6:4
{
temp=0;
for(i=k,j=0;i>=0;i--,j++)
temp+=C(x,i)*C(y,j)*pow((1-gw1),i)*pow(gw1,(x-i))*pow((1-gw2),j)*pow(gw2,(y-j));
if(k%2==0)
{temp*=gw2;y++;}
else
{temp*=gw1;x++;}
res+=temp;
}
//7:5
x=5;y=5;temp=0;
for(i=5,j=0;i>=0;i--,j++)
temp+=C(x,i)*C(y,j)*pow((1-gw1),i)*pow(gw1,(x-i))*pow((1-gw2),j)*pow(gw2,(y-j));
temp=temp*((gw1*gw2)/(gw1*gw2+(1-gw1)*(1-gw2)));
res+=temp;
return res;
}
int main()
{
int T,i,j,k;
cas=1;
scanf("%d",&T);
while(T--)
{
scanf("%lf%lf",&pw1,&pw2);
pw1/=100;pw2/=100;
gw1=get_g(pw1);
gw2=get_g(pw2);
sw1=get_s(gw1,gw2);
sw2=get_s(gw2,gw1);
//printf("*%.2lf %.2lf %.2lf %.2lf %.2lf %.2lf\n",pw1,pw2,gw1,gw2,sw1,sw2);
double ans=0,temp;
int x=1,y=1;
for(k=0;k<=2;k++)//3:0--3:2
{
temp=0;
for(i=k,j=0;i>=0;i--,j++)
temp+=C(x,i)*C(y,j)*pow((1-sw1),i)*pow(sw1,(x-i))*pow((1-sw2),j)*pow(sw2,(y-j));
if(k%2==0)
{temp*=sw1;x++;}
else
{temp*=sw2;y++;}
ans+=temp;
}
printf("Case #%d: %.4lf%%\n",cas++,ans*100);
}
return 0;
}