bzoj1502(二分)

来源:互联网 发布:阿塞拜疆程序员 编辑:程序博客网 时间:2024/05/18 00:50


§二分L,转化为判断三个边长为L的正方形能否覆盖所有点
§求包含所有点的最小矩形
§一定至少有一个矩形覆盖在角上,枚举在哪个角
§求包含剩下的点的最小矩形
§一定至少有一个矩形覆盖在角上,再枚举在哪个角
§求包含剩下的点的最小矩形
§判断是否小于L*L


#include<cstdio>#include<cmath>#include<cstring>#include<cstdlib>#include<algorithm>using namespace std;const int inf=0x3f3f3f3f;int n;int ax[22005],ay[22005];int mxx,mxy,mix,miy;bool pan(int mid){if (mid>mxx-mix&&mid>mxy-miy) return true;for (int i=1;i<=4;i++){int x,y;switch(i){case 1:x=mxx,y=mxy;break;case 2:x=mxx,y=miy;break;case 3:x=mix,y=miy;break;case 4:x=mix,y=mxy;break;}int txx,txy,tix,tiy;txx=txy=-inf;tix=tiy=inf;for (int j=1;j<=n;j++) if (abs(ax[j]-x)>mid||abs(ay[j]-y)>mid){txx=max(txx,ax[j]);txy=max(txy,ay[j]);tix=min(tix,ax[j]);tiy=min(tiy,ay[j]); } for (int j=1;j<=4;j++){int xx,yy;switch(j){case 1:xx=txx,yy=txy;break;case 2:xx=txx,yy=tiy;break;case 3:xx=tix,yy=tiy;break;case 4:xx=tix,yy=txy;break;}int ttxx,ttxy,ttix,ttiy;ttxx=ttxy=-inf;ttix=ttiy=inf;for (int l=1;l<=n;l++) if (abs(ax[l]-x)>mid||abs(ay[l]-y)>mid)if (abs(ax[l]-xx)>mid||abs(ay[l]-yy)>mid){ttxx=max(ttxx,ax[l]);ttxy=max(ttxy,ay[l]);ttix=min(ttix,ax[l]);ttiy=min(ttiy,ay[l]); }  if (ttxx-ttix<=mid&&ttxy-ttiy<=mid) return true;}}return false;}int main(){scanf("%d",&n);mxx=mxy=-inf;mix=miy=inf;for (int i=1;i<=n;i++) {scanf("%d%d",&ax[i],&ay[i]);mxx=max(mxx,ax[i]);mxy=max(mxy,ay[i]);mix=min(mix,ax[i]);miy=min(miy,ay[i]);}int l=0,r=1e9,mid,ans;while (l<=r){mid=(l+r)>>1;if (pan(mid)){ans=mid;r=mid-1;}else l=mid+1;}printf("%d",ans);return 0;}

总结

1:这里是通过维护横纵坐标的最大最小来维护整个最小点覆盖矩形的。 


0 0