Fishes题解

Fishes题解

我们考虑每一条鱼的贡献,

显然是能被选中的矩形的个数/矩形总数

fish

可知,我们普通的鱼能被选中的矩形个数为r*r[从上至下r,从左至右r],

但是有时会受到矩形大小的限制,

此时x-r+1<1或者x+r-1>n或者y-r+1<1或者y+r-1>m,

能选矩形的下界为min(n-r+1,x),上界为max(1,n-r+1),上下长度为min(n-r+1,x)-max(1,x-r+1)+1=min(n-r+1,x)-max(0,x-r),

同理,左右长度为min(m-r+1,y)-max(0,y-r),个数即为(min(n-r+1,x)-max(0,x-r))×(min(m-r+1,y)-max(0,y-r))。

矩形总数为:(n-r+1)*(n-r+1);

选出k条鱼的方案使期望最大,即是选出前k大期望的正方形格子,越在中间,肯定越不受矩形边界的限制,我们不妨从最中间起,向四周拓展。

代码:

#include<bits/stdc++.h>
using namespace std;
const int N=100006,f[4][2]={{1,0},{-1,0},{0,1},{0,-1}};
map<int,int> ha[N];
int n,m,r,k;
double ans=0.000;
struct xd{
   int x,y;
   double z;
   bool operator < (const xd &a) const {return a.z>z;}
}tmp,nw;
priority_queue<xd> q;
inline int read(){
   int T=0,F=1; char ch=getchar();
   while(ch<'0'||ch>'9'){if(ch=='-') F=-1; ch=getchar();}
   while(ch>='0'&&ch<='9') T=(T<<3)+(T<<1)+(ch-48),ch=getchar();
   return F*T;
}
int main(){
    n=read(),m=read(),r=read(),k=read();
    tmp.x=n/2+1,tmp.y=m/2+1,ha[tmp.x][tmp.y]=1,tmp.z=(min(n-r+1,tmp.x)-max(0,tmp.x-r))*(min(m-r+1,tmp.y)-max(0,tmp.y-r))*1.0000000000000/(n-r+1)*1.0000000000000000/(m-r+1),q.push(tmp);
    for(int i=1;i<=k;++i){
        tmp=q.top(),ans+=tmp.z,q.pop();
        for(int j=0;j<4;++j){
            nw.x=tmp.x+f[j][0],nw.y=tmp.y+f[j][1];
            if(nw.x<1||nw.x>n||nw.y<1||nw.y>m||ha[nw.x].find(nw.y)!=ha[nw.x].end()) continue;
            nw.z=(min(n-r+1,nw.x)-max(0,nw.x-r))*(min(m-r+1,nw.y)-max(0,nw.y-r))*1.0000000000000/(n-r+1)*1.0000000000000000/(m-r+1);
            q.push(nw),ha[nw.x][nw.y]=1;
        }
    }
    printf("%.10lf",ans);
    return 0; 
}
 
posted @ 2019-08-08 08:30  lsoi_ljk123  阅读(111)  评论(0编辑  收藏  举报