zoukankan      html  css  js  c++  java
  • bzoj2969 矩形粉刷

    Description

    为了庆祝新的一年到来,小M决定要粉刷一个大木板。大木板实际上是一个W*H的方阵。小M得到了一个神奇的工具,这个工具只需要指定方阵中两个格子,就可以把这两格子为对角的,平行于木板边界的一个子矩形全部刷好。小M乐坏了,于是开始胡乱地使用这个工具。
    假设小M每次选的两个格子都是完全随机的(方阵中每个格子被选中的概率是相等的),而且小M使用了K次工具,求木板上被小M粉刷过的格子个数的期望值是多少。

    Input

    第一行是整数K,W,H

    Output

    一行,为答案,四舍五入保留到整数。

    100% 的数据满足:(1 leq W,H leq 1000, 0leq K leq 100)


    算被刷的格子个数和的期望,可以转化为每个格子被刷的概率和(和的期望=期望的和)

    可以先算出每个格子一次有多少可能性不被刷,然后给他做一个(k)次方,也就是(k)次都不被刷的概率
    然后用(1)减去这个概率,就是(k)次至少刷一次的概率
    那么这个不被刷的概率,就要先求出有几个矩形不包含((i,j)),也就是选的两个点都在当前这个格子的同一方向,然后再除以矩形总数
    例如((i,j))表示在(i)(j)列,那么在((i,j))的上面有((i-1)cdot m)个点,任意选两个点的方案数是(((i-1)cdot m)^2)种方案
    下,左,右也同理

    不过这样计算会算重复,例如选的两个点都在((i,j))的左上方,会在计算上和左的时候计算两遍,要再减一遍
    以左上为例,要减去的方案数是(((i-1)cdot (j-1))^2)

    然后把重复的去掉就得到刷一次不被刷掉的概率了

    一开始想按矩形四遍在哪一行/列来计算,直接计算能被刷掉的,但错了,应该是方法本身有问题
    也有可能写错了。。

    #include<cstdio>
    #define reg register
    inline double power(double a,int b){
        double ret=1;
        while(b){
            if(b&1) ret*=a;
            a*=a;b>>=1;
        }
        return ret;
    }
    inline double sqr(int x){
    	return (double)x*x;
    }
    int main(){
        int k,n,m;
        std::scanf("%d%d%d",&k,&n,&m);
        double sum=sqr(n*m),ans=0;
        for(reg int i=1;i<=n;i++){
            for(reg int j=1;j<=m;j++){
                double tmp;
    			tmp=sqr((i-1)*m)+sqr((n-i)*m)+sqr((j-1)*n)+sqr((m-j)*n);
    			tmp-=sqr((i-1)*(j-1))+sqr((n-i)*(m-j))+sqr((n-i)*(j-1))+sqr((m-j)*(i-1));
                ans+=1-power(tmp/sum,k);
            }
        }
        std::printf("%.0lf",ans);
    }
    
  • 相关阅读:
    继承
    redis面试题收集
    spring知识点
    jvm类加载
    jvm回收机制
    HashMap和ConcurrentHashMap
    java基础
    spring-quartz整合
    alibaba-sentinel-1.8变化
    springcloud执行流程理解图
  • 原文地址:https://www.cnblogs.com/suxxsfe/p/12552188.html
Copyright © 2011-2022 走看看