HDU

来源:互联网 发布:好听的爱情句子知乎 编辑:程序博客网 时间:2024/06/05 20:22

传送门:-->

Sakura has a very magical tool to paint walls. One day, kAc asked Sakura to paint a wall that looks like an M×NM×N matrix. The wall has M×NM×N squares in all. In the whole problem we denotes (x,y)(x,y) to be the square at the xx-th row, yy-th column. Once Sakura has determined two squares (x1,y1)(x1,y1) and (x2,y2)(x2,y2), she can use the magical tool to paint all the squares in the sub-matrix which has the given two squares as corners. 

However, Sakura is a very naughty girl, so she just randomly uses the tool for KKtimes. More specifically, each time for Sakura to use that tool, she just randomly picks two squares from all the M×NM×N squares, with equal probability. Now, kAc wants to know the expected number of squares that will be painted eventually.
Input
The first line contains an integer TT(T100T≤100), denoting the number of test cases. 

For each test case, there is only one line, with three integers M,NM,N and KK
It is guaranteed that 1M,N5001≤M,N≤5001K201≤K≤20
Output
For each test case, output ''Case #t:'' to represent the tt-th case, and then output the expected number of squares that will be painted. Round to integers.
Sample Input
23 3 14 4 2
Sample Output
Case #1: 4Case #2: 8          
Hint
The precise answer in the first test case is about 3.56790123.
题目大意:

  有一个n*m的矩阵有n*m个方格,然后有一个魔法棒可以用k次,每次可以随意在矩阵上确定两个点,然后以这两个点为对角线的子矩阵中的方格都会被染色。然后求档用完这k次后所被染色的方格数的期望是多少。

题解:

可以这样想一下,考虑每一方格的贡献率,也就是每个方格期望。先考虑用一次魔法棒的情况,在整个矩阵中要任意选两个点,选第一个点的时候有n*m种可能,选第二个点的时候也有 这么多种可能。总的选两个点也就是有n*n*m*m种可能。那么对于任意一个点(x,y)来说有多少种可能不被选到呢?可能选从第0列到y-1列的或者y+1到m列的或者第0到x-1行的或者选第x+1到n行的,这样才不会把(x,y)包含进去吧。那么可以统计一下这四种情况的可能情况数,可能数的计算和计算n*n*m*m一样,对于每个子矩阵都有选两个点的情况那就把这个子矩阵的大小面积乘一下就行了。那么这四种情况中会发现有重复计算的子矩阵,那就是四个角的重复计算的。既然重复计算了,那就减去就行了。当计算出在用一次魔法棒时(x,y)不会被染色的情况数的时候在除以总的情况就是该点的概率了,因为数就一个也就是点(x,y),所以期望就是概率p了,看好了这是(x,y)不被涂色的时候,那么k次都不被涂色的情况就是p^k,被涂色就是(1-p)了。然后充计每个点的期望就是总的期望了。


#include <iostream>#include <bits/stdc++.h>using namespace std;typedef long long LL;int main(){    int t,n,m,k,w=0;    scanf("%d",&t);    while(t--)    {        scanf("%d%d%d",&n,&m,&k);        LL sum=(LL)n*n*m*m;///中间的运算不要用double丢精度        double num=0.0;        for(int x=1;x<=n;x++)        {            for(int y=1;y<=m;y++)            {                LL ans=0;///中间的运算不要用double 丢精度                ans+=(LL)(x-1)*m*(x-1)*m;                ans+=(LL)(n-x)*m*(n-x)*m;                ans+=(LL)(y-1)*n*(y-1)*n;                ans+=(LL)(m-y)*n*(m-y)*n;                ans-=(LL)(x-1)*(y-1)*(x-1)*(y-1);                ans-=(LL)(m-y)*(x-1)*(m-y)*(x-1);                ans-=(LL)(y-1)*(n-x)*(y-1)*(n-x);                ans-=(LL)(n-x)*(m-y)*(n-x)*(m-y);                double ave=(double)ans*1.0/sum;                double ant=1.0;                for(int i=1;i<=k;i++)ant*=ave;                //cout<<ans<<" "<<ave<<endl;                num+=(1-ant);            }        }        printf("Case #%d: %.0f\n",++w,num);    }    return 0;}


0 0
原创粉丝点击