题目大意:给出一个多面体,这个多面题的每个面的数字就是得分,然后给出抛到那几个面可以在获得重抛的机会,求得分的期望,如果是无限大的值就输出inf。
解题思路:得分的期望也就是可能的分值,也就是对应的面的概率乘以对应的面的分值,然后所有的相加。如果没有可以重抛的条件,得分的期望是a0。但是如果有重抛的条件的话就说明获得了一次重抛的机会:这样的机会下的得分的期望就是 能够得到重抛机会的面的 (数目/总数目)=q * 第一次的得分期望a0。这样进行n次就是一个等比数列。首项a0,公比为q,求和公式 a0 (1 - q^n) / 1- q,因为n是接近无穷大的话,那么因为q >= 0 and q<=1,这样 1- q^ n接近于1,这个等比求和公式就是a0 / 1- q。这里的q需要不等于1.等于1的话就说明重抛的概率是1,(如果ao != 0 )这样的分是无限大。如果a0等于0的话,这样的得分期望一定是0.如果不是这样两种情况,就是a0 / 1- q;这里要注意double的精度问题,精度度误差是在- 1e- 6 --- 1e-6,在这个范围内的都是容许存在的误差。
代码:
#include <stdio.h>
#include <string.h>
#include <math.h>
const int N = 205;
int s[N], n, m, vis[N];
int main () {
while (scanf ("%d", &n ) == 1) {
for (int i = 0; i < n; i++)
scanf ("%d", &s[i]);
scanf ("%d", &m);
int x, m1 = m;
memset (vis, 0, sizeof (vis));
for (int i = 0; i < m; i++) {
scanf ("%d", &x);
if (!vis[x])
vis[x] = 1;
else
m1--;
}
m = m1;
double q = (double) m/ (double) n;
double a0 = 0;
for (int i = 0; i < n; i++)
a0 += s[i];
a0 = a0 / n;
if (fabs(a0) == 0)
printf ("0.00\n");
else if (fabs(1 - q) < 1e-6)
printf ("inf\n");
else
printf ("%.2f\n", a0 / ( 1 - q ));
}
return 0;
}