Lights inside 3D Grid LightOJ - 1284
题意:
在一个三维的空间,每个点都有一盏灯,开始全是关的,
现在每次随机选两个点,把两个点之间的全部点,开关都按一遍;问k次过后开着的灯的期望数量;
题解:对每个点 单独计算贡献,即k次过后每个点开关被按了奇数次的期望
对于每个点来说,要使得该点开关被按过,那么选择的两个点不能在该点的同侧,即三个方向上都在两侧
这样的概率为$P = frac{(X cdot X - (i - 1) cdot (i - 1) - (X - i) cdot (X - i))} {X cdot X} cdot Y方向上的 cdot Z方向上的 $
现在计算k次过后开关被按了奇数次的期望,定义f(K)为所求,则有递推如下
(f(K) = (1 - P)cdot f(K - 1) + P cdot (1 - f(K-1)))
化简得(f(K) = frac{1 - (1-2p)^K}{2})
#include<bits/stdc++.h>
#define LL long long
using namespace std;
const double eps = 1e-6;
double cal(int limit,int x){
return (1.0 * limit * limit - (x - 1) * (x - 1) - (limit - x) * (limit - x)) / limit / limit;
}
double qpow(double x,int y){
double ans = 1;
while(y){
if(y & 1) ans = ans * x;
x = x * x,y >>= 1;
}
return ans;
}
int main()
{
int T, cas = 1;
cin>>T;
while(T--){
int X,Y,Z,K;
scanf("%d%d%d%d",&X,&Y,&Z,&K);
printf("Case %d: ",cas++);
double ans = 0;
for(int i = 1;i <= X;i++)
for(int j = 1;j <= Y;j++)
for(int z = 1;z <= Z;z++){
double p = cal(X,i) * cal(Y,j) * cal(Z,z);
ans += (1 - qpow(1 - 2 * p,K))/ 2;
}
printf("%.12lf
",ans);
}
return 0;
}