Play the Dice
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65535/32768 K (Java/Others)Total Submission(s): 1830 Accepted Submission(s): 591
Special Judge
The first line is an integer n (2<=n<=200), following with n integers a i(0<=a i<200)
The second line is an integer m (0<=m<=n), following with m integers b i(1<=b i<=n), which are the numbers of the special sides to get another more chance.
6 1 2 3 4 5 6 0 4 0 0 0 0 1 3
3.50 0.00
题意:
有一个骰子有n个面,每个面都有一个数字,分别是1~n。现让你投一次骰子,你可以得到骰子朝上的那个面的数字的金额。但有m个面中的数字有些特别,因为假如你投的骰子朝上的那个面是那些数字的话,你不仅可以得到那个面的数字的金额,而且还可以再投一次。问你玩一次这样的游戏能得到的金额的期望是多少?
分析:
第一次投到每个数字的几率都是一样的:1/n,所以第一次期望是sum/n。然后有可能投到那些特别的数字,这样就有第二次机会,第二次的期望是sum*m/n(投到特别数字的几率是m/n,sum为数字总和)。类似的第三次的期望:sum*(m/n)*(m/n)。然后假设总共投了k次,根据期望的可加性:总的期望 E = sum/n*(1+m+m*m/n+m*(m/n)^2...) 里面共k项,它是等比数列,根据等比数列求和公式可以求得(中间还利用了极限理论):E = sum/(n-m)。一开始我没推出公式,于是直接写了个循环判断精度,然后各种WA==
本题还需注意的一个地方就是即使m == n也就是骰子所有面的数都是特殊的数时answer也不一定是inf,因为所有面的值都为0的情况answer就是0,而不是inf。。
code:
#include<stdio.h>
#include<string.h>
#include<iostream>
#include<string>
#include<algorithm>
using namespace std;
int main()
{
int n, m, a, b;
while(~scanf("%d", &n))
{
double sum = 0;
for(int i=1; i<=n; i++)
{
scanf("%d", &a);
sum += a;
}
scanf("%d", &m);
for(int i=1; i<=m; i++)
scanf("%d", &b);
if(sum == 0) {printf("0.00\n"); continue;} //没写WA
if(m == n) {printf("inf\n"); continue;}
printf("%.2f\n", sum/(n-m));
}
return 0;
}
由于马上要去上海邀请赛了,所以最近经常模拟比赛。上一场的比赛题目还没搞懂,下一场比赛就来了==。现在很多题也都不愿写题解了,感觉挺麻烦,,还是看心情吧==