该题的网格大小非常大,看似需要离散化,但是实际上是不需要的 。 因为我们可以发现,既然要求正方形里没有树,我们不妨直接枚举树就可以了 。 所以我们将纵坐标单独拿出来从小到大排序,二重循环就可以枚举出矩形上下界,然后关键是横坐标的枚举。 同样,我们将横坐标排序,然后判断对应的纵坐标是否在上下界范围内,通过观察,如果不在,那么这个点将不在当前枚举的矩形中,所以直接跳过就可以了,这样的话,我们只需要一个变量来动态维护左边界就可以了 。
细节 参见代码:
#include<bits/stdc++.h> using namespace std; int T,n,w,h,y[105],len; struct point{ int x,y; }a[105]; bool cmp(point a,point b) { return a.x < b.x || (a.x == b.x && a.y < b.y); } void solve() { sort(a,a+n,cmp); sort(y,y+n+2); len = unique(y,y+n+2) - y; //只是减少一点复杂度 int ansx,ansy,ans = -1,hh,ww; for(int i=0;i<len;i++) { for(int j=i+1;j<len;j++) { hh = y[j] - y[i]; //矩形的高度 int cur_x = 0; for(int k=0;k<n;k++) { if((a[k].y <= y[i] || a[k].y >= y[j])) continue; ww = a[k].x - cur_x; //矩形的宽度 ww = min(ww,hh); //取最大正方形 if(ans < ww) { ansx = cur_x; ansy = y[i]; ans = ww; } cur_x = a[k].x; } ww = w - cur_x; ww = min(ww,hh); if(ans < ww) { ansx = cur_x; ansy = y[i]; ans = ww; } } } printf("%d %d %d\n",ansx,ansy,ans); if(T) printf("\n"); } int main() { scanf("%d",&T); while(T--) { scanf("%d%d%d",&n,&w,&h); for(int i=0;i<n;i++) { scanf("%d%d",&a[i].x,&a[i].y); y[i] = a[i].y; } y[n] = 0; y[n+1] = h; //添加边界值,重复也没有关系,还要去重 solve(); } return 0; }
版权声明:本文为博主原创文章,未经博主允许不得转载。
时间: 2024-10-13 06:20:24