[BZOJ2969] 矩形粉刷
阿新 • • 發佈:2020-08-07
[BZOJ2969] 矩形粉刷
為了慶祝新的一年到來,小M決定要粉刷一個大木板。大木板實際上是一個\(W×H\)的方陣。小M得到了一個神奇的工具,這個工具只需要指定方陣中兩個格子,就可以把這兩格子為對角的,平行於木板邊界的一個子矩形全部刷好。小M樂壞了,於是開始胡亂地使用這個工具。
假設小M每次選的兩個格子都是完全隨機的(方陣中每個格子被選中的概率是相等的),而且小M使用了\(K\)次工具,求木板上被小M粉刷過的格子個數的期望值是多少。Input
第一行是整數\(K,W,H\)
Output
一行,為答案,四捨五入保留到整數。
Example
輸入 #1
\(1\) \(3\) \(3\)
輸出 #1
\(4\)
Explanation
標準答案約為3.57
Scoring
\(100%\)的資料滿足:\(1≤W,H≤1000,1≤K≤100\)
比賽時候突然開光想出來了orz,有丶像去年J組第三題
對於每個格子,考慮一個隨機的矩形不能塗到它的概率有多少
顯然,對於一個點\((i,j)\),如果選出的兩個點都在它的上面/下面/左邊/右邊肯定是覆蓋不到它的
把兩個點都在上下左右的概率加起來,再減去都在左上角/右上角/左下角/右上角的概率(這些算了兩遍),就是執行一遍操作時,\((i,j)\)覆蓋不到的概率,設這個數為\(p\)
最後答案就把每個點的\((1-p^k)\)加起來就好了
毫無可讀性的程式碼:
//:D #include<bits/stdc++.h> using namespace std; int k, w, h; double pic[1005][1005]; double Pow(double a, int x) { double s = 1.0; while (x--) s *= a; return s; } int main() { scanf("%d %d %d", &k, &w, &h); for (int i = 1; i <= w; i++) {//行 for (int j = 1; j <= h; j++) {//列 double qwq= Pow(1.0 * (i - 1) / w, 2) + Pow(1.0 * (w - i) / w, 2)//全在上面+全在下面 +Pow(1.0 * (j - 1) / h, 2) + Pow(1.0 * (h - j) / h, 2)//全在左邊+全在右邊 -Pow(1.0 * (i - 1) / w, 2) * Pow(1.0 * (j - 1) / h, 2)//-全在左上 -Pow(1.0 * (i - 1) / w, 2) * Pow(1.0 * (h - j) / h, 2)//-全在左下 -Pow(1.0 * (w - i) / w, 2) * Pow(1.0 * (j - 1) / h, 2)//-全在右上 -Pow(1.0 * (w - i) / w, 2) * Pow(1.0 * (h - j) / h, 2);//-全在右下 //cout<<qwq<<" "; pic[i][j] = qwq; } //cout<<endl; } double cnt = 0.0; for (int i = 1; i <= w; i++) { for (int j = 1; j <= h; j++) { cnt += (1 - Pow(pic[i][j], k)); //cout<<cnt<<endl; } } cout<<(int)(cnt + 0.5); return 0; }
但我還是想看歡天喜地