UVA-1312 Cricket Field (技巧枚举)
题目大意:在一个w*h的网格中,有n个点,找出一个最大的正方形,使得正方形内部没有点。
题目分析:寻找正方形实质上等同于寻找矩形(只需令长宽同取较短的边长)。那么枚举出所有可能的长宽组合取最优答案即可,如何枚举长宽组合呢?通过两重循环枚举纵坐标来确定矩形的一条边长,枚举点的横坐标来完成对另一条边长的枚举。这样一来,就可以把所有的矩形都枚举遍。
代码如下:
# include<iostream> # include<cstdio> # include<cstring> # include<algorithm> using namespace std; struct XY { int x,y; bool operator < (const XY &a) const { if(x==a.x) return y<a.y; return x<a.x; } }; XY xy[105]; int d[105],n,w,h; void solve() { sort(xy+1,xy+n+1); sort(d,d+n+2); int ans=0,ansx,ansy; for(int i=0;i<=n+1;++i){ for(int j=i+1;j<=n+1;++j){ int high=d[j],low=d[i],temp=0,r=d[j]-d[i],c; for(int k=1;k<=n;++k){ if(xy[k].y<=low||xy[k].y>=high) continue; c=xy[k].x-temp; if(ans<min(r,c)){ ans=min(r,c); ansx=temp,ansy=low; } temp=xy[k].x; } c=w-temp; if(ans<min(r,c)){ ans=min(r,c); ansx=temp,ansy=low; } } } printf("%d %d %d\n",ansx,ansy,ans); } int main() { int T; scanf("%d",&T); while(T--) { scanf("%d%d%d",&n,&w,&h); d[0]=0,d[n+1]=h; for(int i=1;i<=n;++i){ scanf("%d%d",&xy[i].x,&xy[i].y); d[i]=xy[i].y; } solve(); if(T) printf("\n"); } return 0; }