InputThe first line contains an integer TT(T≤100T≤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 1≤M,N≤5001≤M,N≤500, 1≤K≤201≤K≤20.
OutputFor 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 Inputios
2 3 3 1 4 4 2
Sample Outputdom
Case #1: 4 Case #2: 8
Hintspa
The precise answer in the first test case is about 3.56790123.
题意:.net
给出一个M*N的矩阵,从其中任意的选两个格子,将以两个格子为对角的矩形染色。这样的操做重复k次,问会被涂色的格子数的指望值。debug
分析:xml
指望值说白了就是执行完上述操做后,计算最有可能涂了多少个格子。blog
看了网上的题解才明白,咱们只须要计算每个格子可能被选中的几率,three
指望值E(x)=x1*p1 + x2*p2 + ..... + xn*pn;事件
在这里咱们把每1个格子看作独立事件,因此这里的x1=x2=.....=xn=1,ip
因此对于本题,指望值 E(x)=p1 + p2 + ..... + pn;
解题:
如今问题就简化成了求 每个格子 被选中的几率,再累加便可。
先看一张图:
假设如今咱们求5这个点被涂色的几率,怎样可让他染上色呢?
选点(x1,y1)和 (x2,y2)构成的矩形包含5这个点便可。
在矩阵中选两个点的总状况数 是 m*n * m*n
那么选点有9种状况:
一、若(x1,y1)在区域1,则(x2,y2)能够在区域五、六、八、9
二、若(x1,y1)在区域3,则(x2,y2)能够在区域四、五、七、8
三、若(x1,y1)在区域7,则(x2,y2)能够在区域二、三、五、6
四、若(x1,y1)在区域9,则(x2,y2)能够在区域一、二、四、5
五、若(x1,y1)在区域2,则(x2,y2)能够在区域四、五、六、七、八、9
六、若(x1,y1)在区域4,则(x2,y2)能够在区域二、三、五、六、八、9
七、若(x1,y1)在区域6,则(x2,y2)能够在区域一、二、四、五、七、8
八、若(x1,y1)在区域8,则(x2,y2)能够在区域一、二、三、四、五、6
九、若(x1,y1)在区域5,则(x2,y2)能够在任意区域
当前这个点被染色的几率就是这9种状况之几率和。
---------------------
参考博客:https://blog.csdn.net/winter2121/article/details/71082686
#include <map> #include <set> #include <stack> #include <cmath> #include <queue> #include <cstdio> #include <vector> #include <string> #include <bitset> #include <cstring> #include <iomanip> #include <iostream> #include <algorithm> #define ls (r<<1) #define rs (r<<1|1) #define debug(a) cout << #a << " " << a << endl using namespace std; typedef long long ll; const ll maxn = 1e3+10; const ll mod = 1e9+7; const double pi = acos(-1.0); const double eps = 1e-8; int main() { ll T, k; double n, m; scanf("%lld",&T); for( ll cas = 1; cas <= T; cas ++ ) { scanf("%lf %lf %lld",&m,&n,&k); double sum = n*m*n*m, ans = 0; //sum:全部的状况种数,ans:指望值 for( ll i = 1; i <= m; i ++ ) { for( ll j = 1; j <= n; j ++ ) { //对每个点算贡献值 double p = 0; //点(i,j)被选中的状况数 //另一个点在区域1,3,5,7 p += (i-1)*(j-1)*(m-i+1)*(n-j+1); p += (i-1)*(n-j)*(m-i+1)*j; p += (m-i)*(j-1)*i*(n-j+1); p += (m-i)*(n-j)*i*j; //另一个点在区域2,4,6,8 p += (i-1)*1*(m-i+1)*n; p += 1*(j-1)*m*(n-j+1); p += 1*(n-j)*m*j; p += (m-i)*1*i*n; //另一个点在区域5 p += m*n; //点(i,j)被选中的几率 p = (p*1.0)/sum; ans += 1-pow(1-p,k); } } printf("Case #%lld: %.0f\n",cas,ans); } return 0; }