Fishes题解
Fishes题解
我们考虑每一条鱼的贡献,
显然是能被选中的矩形的个数/矩形总数
可知,我们普通的鱼能被选中的矩形个数为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;
}