[BZOJ2969] 矩形粉刷

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

但我还是想看欢天喜地

posted @ 2020-08-07 12:29  七离符  阅读(340)  评论(0)    收藏  举报