#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <string>
#include <cmath>
#include <queue>
#include <map>
using namespace std;
int n,m,r;
long long k;
long long get(int x,int y)
{
long long ans=0;
long long xnum=0;
long long ynum=0;
long long xmax=n-r+1;
long long ymax=m-r+1;
if(x==r)
{
int sta=r;
int end=n-r+1;
xnum=max(0,end-sta+1);
} else {
if (x < xmax)
{
int s1=x;
int s2=n-x+1;
if(s1==s2)
xnum=1;
else
xnum=2;
}
else if(x==xmax)
{
int sta=x;
int end=n-x+1;
xnum=max(0,end-sta+1);
} else
return 0;
}
if(y==r)
{
int sta=r;
int end=m-r+1;
ynum=max(0,end-sta+1);
} else {
if (y < ymax)
{
int s1=y;
int s2=m-y+1;
if(s1==s2)
ynum=1;
else
ynum=2;
}
else if(y==ymax)
{
int sta=y;
int end=m-y+1;
ynum=max(0,end-sta+1);
} else
return 0;
}
return xnum*ynum;
}
struct node
{
long long num;
long long val;
long long l,r;
friend bool operator<(node a,node b)
{
return a.val<b.val;
}
node(){}
node(long long tn,long long tv,long long tl,long long tr)
{
num=tn;val=tv;l=tl;r=tr;
}
};
bool cmp(node a,node b)
{
return a.val>b.val;
}
int main() {
while(~scanf("%d%d%d%lld",&n,&m,&r,&k))
{
double total=1.0*(n-r+1)*(m-r+1);
long long xlen=min(r,n-r+1),ylen=min(r,m-r+1);
double ans=0;
priority_queue<node> q;
map<pair<long long,long long>, int> vis;
node sta=node(get(xlen,ylen),xlen*ylen,xlen,ylen);
q.push(sta);
vis[make_pair(xlen,ylen)]=1;
while(!q.empty())
{
node cur=q.top();
q.pop();
long long tnum=min(k,cur.num);
ans+=1.0*cur.val*tnum;
k-=tnum;
if(k==0)
break;
if(cur.l>1 && vis[make_pair(cur.l-1,cur.r)]!=1)
{
node next=node(get(cur.l-1,cur.r),(cur.l-1)*cur.r,cur.l-1,cur.r);
q.push(next);
vis[make_pair(cur.l-1,cur.r)]=1;
}
if(cur.r>1 && vis[make_pair(cur.l,cur.r-1)]!=1)
{
node next=node(get(cur.l,cur.r-1),(cur.l)*(cur.r-1),cur.l,cur.r-1);
q.push(next);
vis[make_pair(cur.l,cur.r-1)]=1;
}
}
ans/=total;
printf("%.10f\n",ans);
}
return 0;
}
D. Fishes cf912d 优先队列+计数
猜你喜欢
转载自blog.csdn.net/c_czl/article/details/88296366
今日推荐
周排行