题目链接:D. Fishes
题意:在一个nm的鱼塘中放入k条鱼你用一个rr的渔网抓鱼,求抓到多少条鱼的最大期望
题解:对于一个位置来说,他可以被网覆盖(min(n+1,x+r)-max(x,r))(min(m+1,y+r)-max(y,r));次我们只要找到k个较大位置对应覆盖次数之和
然后除(((n+1-r)(m+1-r)))就是答案,怎样找到那k个位置呢,我们可以发现(n+1)/2,(m+1)/2,肯定是最大的,然后我们可以用最小优先队列
+搜索周围较小的位置,复杂度为o(klogk);
#include<bits/stdc++.h>
#include<iostream>
#include<string>
#include<cstring>
#include<algorithm>
#define pb push_back
#define ll long long
#define PI 3.14159265
#define ls l,m,rt<<1
#define rs m+1,r,rt<<1|1
#define eps 1e-7
const int mod=1e9+7;
const int maxn=1e5+5;
using namespace std;
set<pair<int,int>>vis;
int dx[]={-1,1,0,0};
int dy[]={0,0,-1,1};
pair<int,int>aa;
ll m,n,r,k;
struct node
{
int x,y;
ll v;
bool operator<(const node &b)const
{
return v<b.v;
}
};
ll va(ll x,ll y)
{
return (min(n+1,x+r)-max(x,r))*(min(m+1,y+r)-max(y,r));
}
int main()
{
std::ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
cin>>m>>n>>r>>k;
priority_queue<node>st;
node s;
s.x=(n+1)/2;s.y=(m+1)/2;s.v=va(s.x,s.y);
st.push(s);
ll ans=0;
aa.first=s.x;aa.second=s.y;
vis.insert(aa);
while(k--)
{
node tmp;
s=st.top();
st.pop();
ans+=s.v;
// cout<<s.x<<' '<<s.y<<' '<<s.v<<endl;
for(int i=0;i<4;i++)
{
tmp.x=s.x+dx[i];
tmp.y=s.y+dy[i];
aa.first=tmp.x;
aa.second=tmp.y;
if(vis.count(aa)||tmp.x<1||tmp.x>n||tmp.y<1||tmp.y>m)continue;
vis.insert(aa);
//cout<<aa.first<<'*'<<aa.second<<endl;
tmp.v=va(tmp.x,tmp.y);
// cout<<tmp.x<<' '<<tmp.y<<' '<<tmp.v<<endl;
st.push(tmp);
}
}
// cout<<ans<<endl;
double tt=(double)ans/((n+1-r)*(m+1-r));
cout<<fixed<<setprecision(10)<<tt<<endl;
return 0;
}