UVA2689 Cricket Field --- 枚举+离散化

题意:给定w*h(w,h<10000)的方格图,给不超过100个点的坐标,点位于交叉线上,求内部不含点的最大正方形面积

题解: 参考自 https://blog.csdn.net/accelerator_/article/details/19000217

把找正方形转换为找矩形,找到矩形取Min(w,h)即为内含的正方形,这样就简化了题目,找矩形的话,需要确定4边,枚举边的位置肯定不是在w,h里面枚举,而是在有点的横线或竖线中枚举,所以就先枚举2条任意竖线,但是要把x=0和x=w加入,然后遍历所有点,找夹在2条竖线之间的点,找出他们所有的y坐标,然后枚举相邻2条y线,即形成一个满足题意的矩形,找出所有矩形中内含正方形面积最大的即可。 

#include <cstdio>
#include <cstring>
#include <algorithm>
#define MAXN 110
using namespace std;
int n,w,h;
struct Point {
  int x,y;
} p[MAXN];
int xn,yn; // record how many x or y lines there are 
int xpos[MAXN],ypos[MAXN];

// sort by coordinate x
bool cmp_x(Point a,Point b) {
  return a.x < b.x;
}

// sort by coordinate y
bool cmp_y(Point a,Point b) {
  return a.y < b.y;
}


int main() {
  int T;
  scanf("%d",&T);
  while(T--) {
    scanf("%d%d%d",&n,&w,&h);
    for(int i = 0;i < n;i++) {
      scanf("%d%d",&p[i].x,&p[i].y);
    }
    memset(xpos,0,sizeof(xpos));
    memset(ypos,0,sizeof(ypos));
    xn = 0;
    yn = 0;
    xpos[xn++] = 0;
    sort(p,p+n,cmp_x);
    for(int i = 0;i < n;i++) {
      if(p[i].x==0||p[i].x==w) continue;
      if(i==0 || p[i].x!=p[i-1].x) {
        xpos[xn++] = p[i].x;
      }
    }
    xpos[xn++] = w;
    int res = 0;
    int res_x,res_y;
    for(int i = 0;i < xn;i++)
      for(int j = i+1;j < xn;j++) {
        int x1 = xpos[i];
        int x2 = xpos[j];

        yn = 0;
        sort(p,p+n,cmp_y);
        ypos[yn++] = 0;
        for(int k = 0;k < n;k++) {
          if(p[k].y==0||p[k].y==h) continue;
          if(!(p[k].x>x1&&p[k].x<x2)) continue;
          if(p[k].y != ypos[yn-1]) {
            ypos[yn++] = p[k].y;
          }
        }
        ypos[yn++] = h;

        for(int k = 1;k < yn;k++) {
          int y1 = ypos[k-1];
          int y2 = ypos[k];
          int len_y = abs(y1-y2);
          int len_x = abs(x1-x2);
          int t = min(len_x,len_y);
          if(t > res) {
            // if(t==5) {
            //   printf("%d %d %d %d\n",x1,x2,y1,y2);
            // }
            res = t;
            res_x = x1;
            res_y = y1;
          }
        }
      }
    printf("%d %d ",res_x,res_y);
    printf("%d\n",res);
    if(T) printf("\n");
  }

  return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值