题目地址: http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=4030
只要在哪一个状态下是小的那个赢了,游戏就结束。 所以我们考虑最坏的情况,每次都是小的赢,自己变为两倍。想起了之前选拔赛那个两个盒子之间球倒来倒去那个题。当时只要超过1000次就认为进入循环了。
这里计算概率也要分两种情况,进入循环和不进入循环。 不进入循环就会在某一时刻a【k】==b【k】。 意味着会有k+1轮, 对于期望,最后一个不再是(k+1)*0.5^(k+1) 指数减少一,于是我们就再加上一个最后加的,break掉。
对于概率,则是在a【k】>=b【k】时才加上相应的概率。 角标和指数之间的关系举个具体的例子就很清楚了。
#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
int a[1001];
int b[1001];
int main()
{
int T;
cin>>T;
int x,y;
int index=0;
while(cin>>x>>y)
{
index++;
cout<<"Case "<<index<<": ";
memset(a,0,sizeof(a));
memset(b,0,sizeof(b));
a[0]=x;
b[0]=y;
for(int i=1;i<=1000;i++)
{
if(a[i-1]==b[i-1]) break;
else if(a[i-1]>b[i-1])
{
a[i]=a[i-1]-b[i-1];
b[i]=2*b[i-1];
}
else
{
a[i]=2*a[i-1];
b[i]=b[i-1]-a[i-1];
}
}
double round=0;
double pa=0;
double pow2=1;
for(int i=0;i<=1001;i++)
{
pow2/=2;
round+=pow2*(i+1);
if(a[i]>=b[i])
{
pa+=pow2;
}
if(a[i]==b[i])
{
round+=pow2*(i+1);
break;
}
}
// cout<<round<<" "<<pa<<endl;
printf("%.6lf %.6lf
",round,pa);
}
}