Codeforces Round #456 (Div. 2)D. Fishes

题目链接: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;
}
原文地址:https://www.cnblogs.com/lhclqslove/p/8261961.html