Lights inside 3D Grid LightOJ

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;
}
原文地址:https://www.cnblogs.com/jiachinzhao/p/7205184.html