魚の問題解決
私たちは、それぞれの魚の寄与を考慮し、
数が矩形の矩形/合計数を選択することは明らかです
私たち普通の魚は矩形番号がR * rのある選択可能であることを示している[上から下rに、右R左から]、
しかし、時には長方形の大きさによって制限され、
このとき、xは、R + 1 <1、X + R-1> nまたはY-R + 1 <1、またはY + R-1> M、
分の縦方向の長さ(N-R + 1、X)-max(1、X、長方形の下限分(N-R + 1、x)は、MAX(1、N-R + 1)の上限から選択することができます。 -r + 1)+ 1 =分(N-R + 1、X)-max(0、XR)、
同様に、左右の長さ分(M-R + 1、Y)-max(0年)、つまり、数(MIN(N-R + 1、X)-max(0、XR))×(分(M-R + 1、Y)-max(0、年))。
総矩形:(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;
}