• CF912D Solution


    题目链接

    题解

    ⭐:在有规律的矩阵中求最大值,可以考虑使用类最短路的搜索。

    易得答案为(k)个格子覆盖次数和(div (n-r+1)^2),因此只需找出覆盖次数最大的(k)个格子。所以——打表找规律!

    格子((tx,ty))被覆盖的次数如下:设(x=min(tx,n-tx+1),y=min(ty,m-ty+1))(上下、左右对称),次数(=min(r,n-r+1,x)cdot min(r,m-r+1,y))。其实也可以推导得出:若矩形无限大,覆盖次数一定(=r^2)(网中所有位置均占一遍);但矩形的边界限制其上下最多(x)个,左右最多(y)个;至于(n-r+1,m-r+1)则是行列最多覆盖次数,3者取(min),乘积即为答案。

    由上式得覆盖次数中间最大,四周最小。因此我们可以由((lceil frac{n}{2} ceil,lceil frac{m}{2} ceil))开始进行BFS,每次向上下左右扩展,并将扩展格子放入优先队列(大根堆)中。进行(k)次求和即可。

    AC代码

    #include<bits/stdc++.h>
    #define int long long
    #define mp make_pair
    using namespace std;
    struct node 
    {
    	int x,y,v;
    	bool operator < (const node& a) const {return v<a.v;}
    };
    int n,m,r; 
    priority_queue<node> q;
    map<pair<int,int>,bool> vis;
    int cul(int x,int y)//求(x,y)的覆盖次数
    {
    	if(x>(n+1)/2) x=n-x+1;
    	if(y>(m+1)/2) y=m-y+1;
    	x=min(min(r,n-r+1),x),y=min(min(r,m-r+1),y);
    	return x*y;
    }
    bool ok(int x,int y) {return 1<=x && x<=n && 1<=y && y<=m && !vis[mp(x,y)];}
    signed main()
    {
    	int k,sum=0,cnt=0; 
    	scanf("%lld%lld%lld%lld",&n,&m,&r,&k);
    	q.push((node){(n+1)/2,(m+1)/2,cul((n+1)/2,(m+1)/2)}),vis[mp((n+1)/2,(m+1)/2)]=1;
    	while(!q.empty())
    	{
    		cnt++; sum+=q.top().v;
    		if(cnt==k) break;
    		int x=q.top().x,y=q.top().y; q.pop();
    		if(ok(x+1,y)) q.push((node){x+1,y,cul(x+1,y)}),vis[mp(x+1,y)]=1;
    		if(ok(x,y+1)) q.push((node){x,y+1,cul(x,y+1)}),vis[mp(x,y+1)]=1;
    		if(ok(x-1,y)) q.push((node){x-1,y,cul(x-1,y)}),vis[mp(x-1,y)]=1;
    		if(ok(x,y-1)) q.push((node){x,y-1,cul(x,y-1)}),vis[mp(x,y-1)]=1;
    	}
    	double ans=sum*1.0/((n-r+1)*(m-r+1));
    	printf("%0.10f",ans);
    	return 0;
    }
    
  • 相关阅读:
    爬虫基础简介
    父子分类与无限分类
    Flask路由层
    Flask基础简介
    DRF之JWT签发,认证,群查
    DRF之JWT简介
    DRF之认证组件
    软件众包外包平台汇总
    Python与机器视觉(x)windows下import cv2报错dll
    【今日CV 视觉论文速览】Fri, 8 Feb 2019
  • 原文地址:https://www.cnblogs.com/violetholmes/p/14616127.html
Copyright © 2020-2023  润新知