题目地址: 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); } }