codeforces912D 2100分bfs

题目传送门

题意:

有一个 \dpi{150}n*m 的矩阵,把每个格子想象成一个小鱼池,每个鱼池最多可以放一条鱼。

你有一个 \dpi{150}r*r 的渔网,捕鱼时渔网覆盖的每个位置都必须在矩阵内。每次渔网覆盖范围内的鱼都可以捕获。

现在你有 \dpi{150} k 条鱼,你可以放置鱼的位置,使任意摆放渔网的位置捕获鱼的个数期望最大。

数据范围: \dpi{150} 1 \leqslant n\;m \leqslant 10^5 , 1 \leqslant r \leqslant min(n\;,m) , 1 \leqslant k \leqslant min(n*m \;, 10^5) 。

题解:

看到题目后感觉可能是推一个结论。

但是看到数据范围发现基本只能是一条一条地摆放每条鱼了。

观察后发现鱼越靠近中间,贡献越多。

中间位置认为是 \dpi{150} (\left\lfloor \frac{n+1}{2} \right\rfloor , \left\lfloor \frac{m+1}{2} \right\rfloor ) 。

然后再观察发现中间位置的旁边紧邻的上下左右的位置是贡献的次大值。

这就可以 \dpi{150}bfs 了。

把一条鱼放在 \dpi{150}(x\;,\;y) 的贡献是

 \dpi{150} min(x , n - r + 1) - max(1 , x - r + 1)) * (min(y , m - r + 1) - max(1 , y - r + 1) 。

计算这个贡献时建议画个图,列不等式方程组。

 然后我们累加 \dpi{150}k 条鱼的贡献,最后还需要除渔网的摆放位置方案数。

渔网的摆放位置方案数是 \dpi{150} (n-r+1)*(m-r+1) 。

感受:

好久没有不看题解1A了,虽然不是什么难题,不过还是比较舒服。

代码:

#include<bits/stdc++.h>
using namespace std ;
typedef long long ll ;
const int maxn = 1e5 + 5 ;
int row[4] = {-1 , 1 , 0 , 0} ;
int col[4] = {0 , 0 , -1 , 1} ;
int n , m , r , k ;
double sum = 0 ;
map<int , bool> vis[maxn] ;
ll cal(int x , int y)
{
	int p = max(1 , x - r + 1) ;
	int q = min(x , n - r + 1) ;
	int s = max(1 , y - r + 1) ;
	int t = min(y , m - r + 1) ;
	return  ll(q - p + 1) * (t - s + 1) ;
}
struct node
{
	int x , y ;
    bool operator < (const node &s) const
	{
	   return cal(x , y) < cal(s.x , s.y) ;	
	}	
} ;
priority_queue<node> q ;
bool can(int x , int y)
{
	return x >= 1 && x <= n && y >= 1 && y <= m && !vis[x].count(y) ;
}
void bfs()
{
	q.push(node{(n + 1) / 2 , (m + 1) / 2}) ;
	vis[(n + 1) / 2][(m + 1) / 2] = 1 ;
	while(k)
	{
		int x = q.top().x ;
		int y = q.top().y ;
		q.pop() ;
		sum += (double)cal(x , y) ;
		k -- ;
		for(int i = 0 ; i < 4 ; i ++)
		{
			int nx = x + row[i] ;
			int ny = y + col[i] ;
			if(can(nx , ny))
			{
				vis[nx][ny] = 1 ;
				q.push(node{nx , ny}) ;
			}
		}
	}
}
int main()
{
	double ans ;
	scanf("%d%d%d%d" , &n , &m , &r , &k) ;
	bfs() ;
	ans = double(n - r + 1) * (m - r + 1) ;
	ans = (double)sum / ans ;
	printf("%.12f\n" , ans) ;
	return 0 ;
}

 

### 回答1: Codeforces估是指在Codeforces比赛中预估自己在比赛结束后所能获得的数。这个数是考虑根据自己的表现和其他参赛者的表现来预估的。 Codeforces数是根据比赛中的排名和成功解决问题的数量来计算的。在每场比赛结束后,每位参赛者会根据其在比赛中的表现被配一个数。比赛中排名越高的参赛者获得的数也越高,而解决更多问题的参赛者同样也能获得更多数。 Codeforces估有两种方法:一种是通过比赛中的实时排名来估计当前数,另一种是通过计算比赛中已解决问题的数来估计最终的总。 对于第一种方法,我们可以在比赛过程中观察自己在排名榜上的位置和其他参赛者的数。如果自己的排名越高,说明自己的数也会越高;如果其他人的数与自己相差较大,说明他们可能已经解决了更多的问题,因此可能获得更高的数。 对于第二种方法,我们可以根据已经解决的问题数量来估算总Codeforces的比赛系统会根据每个问题的难度和重要性配不同的数。因此,如果我们能成功解决更多的问题,我们也将获得更高的数。 总的来说,Codeforces估是一个根据比赛中的排名和解决问题的数量来估计自己数的过程。但是,由于每场比赛的题目和参赛人数不同,预估数可能有一定的不确定性。因此,我们建议在比赛过程中持续观察排名榜和其他参赛者的情况,以及时作出调整和优化自己的策略。 ### 回答2: Codeforces是一个在线的编程竞赛平台,每个竞赛都有一定的难度,需要通过编写代码来解决各种算法和数据结构的问题。Codeforces的估指的是根据你在竞赛中的表现得出的一个评。 在Codeforces竞赛中,你会根据你的解题情况和提交的答案是否正确来获得数。每个问题都有一定的值,解决该问题可以获得该值的数。如果你的答案是正确的,你将获得该问题的数;如果你的答案是错误的,你将不会获得数。 Codeforces的估算法是基于Elo算法改进的。Elo算法是一种用于评估竞技选手水平的算法。该算法会根据你的表现和对手的水平来决定你的数变化。如果你击败了一个数比你高的选手,你的数可能会上升得更多;如果你输给一个数比你低的选手,你的数可能会下降得更多。 Codeforces的估也考虑了竞赛的参与人数。如果你在一个参与人数多的竞赛中获得了好的成绩,你的数可能会得到进一步的提升。相反,如果你在一个参与人数少的竞赛中获得了好的成绩,你的数可能会得到更少的提升。 总的来说,Codeforces的估是根据你的表现、对手的水平和竞赛的参与人数来计算的。通过持续参与竞赛并取得好的成绩,你的数将会逐渐提升。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值