CF912D Fishes 期望

CF912D Fishes 期望

题意翻译

Description

有一个长为nnn ,宽为mmm 的鱼缸,还有一个边长为rrr 的正方形渔网。你可以往鱼缸里放kkk 条鱼,问用渔网随机在浴缸里捞鱼的最大期望是多少。不懂什么是期望的自己去百度

Input

一行4个正整数代表n,m,r,kn, m, r, kn,m,r,k

Output

输出一个实数,表示最大期望

感谢@xunzhen 提供的翻译

题目描述

While Grisha was celebrating New Year with Ded Moroz, Misha gifted Sasha a small rectangular pond of size n×m n×m n×m , divided into cells of size 1×1 1×1 1×1 , inhabited by tiny evil fishes (no more than one fish per cell, otherwise they'll strife!).

The gift bundle also includes a square scoop of size r×r r×r r×r , designed for fishing. If the lower-left corner of the scoop-net is located at cell (x,y) (x,y) (x,y) , all fishes inside the square (x,y)...(x+r−1,y+r−1) (x,y)...(x+r-1,y+r-1) (x,y)...(x+r1,y+r1) get caught. Note that the scoop-net should lie completely inside the pond when used.

Unfortunately, Sasha is not that skilled in fishing and hence throws the scoop randomly. In order to not frustrate Sasha, Misha decided to release k k k fishes into the empty pond in such a way that the expected value of the number of caught fishes is as high as possible. Help Misha! In other words, put k k k fishes in the pond into distinct cells in such a way that when the scoop-net is placed into a random position among (n−r+1)⋅(m−r+1) (n-r+1)·(m-r+1) (nr+1)(mr+1) possible positions, the average number of caught fishes is as high as possible.

输入输出格式

输入格式:

The only line contains four integers n,m,r,k n,m,r,k n,m,r,k ( 1<=n,m<=105 1<=n,m<=10^{5} 1<=n,m<=105 , 1<=r<=min(n,m) 1<=r<=min(n,m) 1<=r<=min(n,m) , 1<=k<=min(n⋅m,105) 1<=k<=min(n·m,10^{5}) 1<=k<=min(nm,105) ).

输出格式:

Print a single number — the maximum possible expected number of caught fishes.

You answer is considered correct, is its absolute or relative error does not exceed 10−9 10^{-9} 109 . Namely, let your answer be a a a , and the jury's answer be b b b . Your answer is considered correct, if .

输入输出样例

输入样例#1: 复制
3 3 2 3
输出样例#1: 复制
2.0000000000
输入样例#2: 复制
12 17 9 40
输出样例#2: 复制
32.8333333333

说明

In the first example you can put the fishes in cells (2,1) (2,1) (2,1) , (2,2) (2,2) (2,2) , (2,3) (2,3) (2,3) . In this case, for any of four possible positions of the scoop-net (highlighted with light green), the number of fishes inside is equal to two, and so is the expected value.

 

 

很容易想到的一种思路是在被正方形覆盖次数最多的地方放?;

那么我们要做的就是给定(x,y)坐标后,求出该位置被多少个矩形所覆盖即可;

接着从该位置向四周拓展----bfs;

当然用 priority-queue维护一下即可解决;

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstdlib>
#include<cstring>
#include<string>
#include<cmath>
#include<map>
#include<set>
#include<vector>
#include<queue>
#include<bitset>
#include<ctime>
#include<deque>
#include<stack>
#include<functional>
#include<sstream>
//#include<cctype>
//#pragma GCC optimize(2)
using namespace std;
#define maxn 300005
#define inf 0x3f3f3f3f
#define INF 9999999999
#define rdint(x) scanf("%d",&x)
#define rdllt(x) scanf("%lld",&x)
#define rdult(x) scanf("%lu",&x)
#define rdlf(x) scanf("%lf",&x)
#define rdstr(x) scanf("%s",x)
typedef long long  ll;
typedef unsigned long long ull;
typedef unsigned int U;
#define ms(x) memset((x),0,sizeof(x))
const long long int mod = 1e9 + 7;
#define Mod 1000000000
#define sq(x) (x)*(x)
#define eps 1e-3
typedef pair<int, int> pii;
#define pi acos(-1.0)
const int N = 1005;
#define REP(i,n) for(int i=0;i<(n);i++)
typedef pair<int, int> pii;
inline ll rd() {
	ll x = 0;
	char c = getchar();
	bool f = false;
	while (!isdigit(c)) {
		if (c == '-') f = true;
		c = getchar();
	}
	while (isdigit(c)) {
		x = (x << 1) + (x << 3) + (c ^ 48);
		c = getchar();
	}
	return f ? -x : x;
}

ll gcd(ll a, ll b) {
	return b == 0 ? a : gcd(b, a%b);
}
ll sqr(ll x) { return x * x; }

/*ll ans;
ll exgcd(ll a, ll b, ll &x, ll &y) {
	if (!b) {
		x = 1; y = 0; return a;
	}
	ans = exgcd(b, a%b, x, y);
	ll t = x; x = y; y = t - a / b * y;
	return ans;
}
*/


double ans = 0;
int n, m, k, r;
int dx[] = { 0,1,0,-1 };
int dy[] = { 1,0,-1,0 };

struct node {
	int x, y;
	ll sum;
	friend bool operator <(node a, node b) {
		return a.sum < b.sum;
	}
};

priority_queue<node>q;
map<pii, int>fg;

bool judge(int x, int y) {
	if (x >= 1 && x <= n && y >= 1 && y <= m&&fg[make_pair(x,y)]==0)return true;
	if (fg[make_pair(x, y)])return 0;
	return 0;
}

ll getsum(int x, int y) {
	ll X = min(n, x + r - 1) - max(r, x) + 1;
	ll Y = min(m, y + r - 1) - max(y, r) + 1;
	return X * Y;
}

int main()
{
	//ios::sync_with_stdio(0);
	rdint(n); rdint(m); rdint(r); rdint(k);
	fg[make_pair((n+1)/2, (m+1)/2)] = 1;
	q.push(node{ (n + 1) / 2,(m + 1) / 2,getsum((n + 1) / 2,(m + 1) / 2) });
	while (k--) {
		node tmp = q.top(); q.pop();
		int x = tmp.x, y = tmp.y;
		ans += 1.0*tmp.sum / (n - r + 1) / (m - r + 1);
		for (int i = 0; i < 4; i++) {
			int nx = x + dx[i], ny = y + dy[i];
			if (judge(nx, ny)) {
				fg[make_pair(nx, ny)] = 1;
				q.push(node { nx, ny, getsum(nx, ny) });
			}
		}
		
	}
	printf("%.10lf\n", 1.0*ans);
	return 0;
}

 

posted @ 2018-12-15 15:32 NKDEWSM 阅读( ...) 评论( ...) 编辑 收藏
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值