[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;
}
但我还是想看欢天喜地