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; }