首页 > 代码库 > 二分判定 覆盖问题 BZOJ 1052

二分判定 覆盖问题 BZOJ 1052

 1 //二分判定 覆盖问题 BZOJ 1052 2 // 首先确定一个最小矩阵包围所有点,则最优正方形的一个角一定与矩形一个角重合。 3 // 然后枚举每个角,再解决子问题 4  5 #include <bits/stdc++.h> 6 using namespace std; 7 #define LL long long 8 typedef pair<int,int> pii; 9 const int inf = 1e9;10 const int MOD =5010;11 const int N =5010;12 #define clc(a,b) memset(a,b,sizeof(a))13 const double eps = 1e-8;14 void fre() {freopen("in.txt","r",stdin);}15 void freout() {freopen("out.txt","w",stdout);}16 inline int read() {int x=0,f=1;char ch=getchar();while(ch>9||ch<0) {if(ch==-) f=-1; ch=getchar();}while(ch>=0&&ch<=9) {x=x*10+ch-0;ch=getchar();}return x*f;}17   18 struct node{19     int x[20010],y[20010];20     int num;21 }a,b;22 int n,mid;23   24 void solve2(node &a,int x1,int y1,int x2,int y2){25     int cnt=0;26     for(int i=0;i<a.num;i++){27         if(a.x[i]<x1||a.x[i]>x2||a.y[i]>y2||a.y[i]<y1){28             a.x[cnt]=a.x[i];29             a.y[cnt]=a.y[i];30             cnt++;31         }32     }33     a.num=cnt;34 }35 void solve(node &a,int f){36     int x1=inf,x2=-inf,y1=inf,y2=-inf;37     for(int i=0;i<a.num;i++){38         x1=min(x1,a.x[i]);39         x2=max(x2,a.x[i]);40         y1=min(y1,a.y[i]);41         y2=max(y2,a.y[i]);42     }43     if(f==1) solve2(a,x1,y1,x1+mid,y1+mid);44     if(f==2) solve2(a,x2-mid,y1,x2,y1+mid);45     if(f==3) solve2(a,x1,y2-mid,x1+mid,y2);46     if(f==4) solve2(a,x2-mid,y2-mid,x2,y2);47 }48 bool check(){49     for(int s=1;s<=4;s++){50         for(int t=1;t<=4;t++){51             b.num=a.num;52             for(int i=0;i<b.num;i++){53                 b.x[i]=a.x[i],b.y[i]=a.y[i];54             }55             solve(b,s),solve(b,t);56             int x1=inf,x2=-inf,y1=inf,y2=-inf;57             for(int i=0;i<b.num;i++){58                 x1=min(x1,b.x[i]);59                 x2=max(x2,b.x[i]);60                 y1=min(y1,b.y[i]);61                 y2=max(y2,b.y[i]);62             }63             if(x2-x1<=mid&&y2-y1<=mid) return true;64         }65     } 66     return false;67 }68 int main(){69     n=read();70     for(int i=0;i<n;i++) a.x[i]=read(),a.y[i]=read();71     a.num=n;72     int l=0,r=inf;73     while(l<=r){74         mid=(l+r)>>1;75         if(check()) r=mid-1;76         else l=mid+1;77     }78     printf("%d\n",l);79     return 0;80 }

 

二分判定 覆盖问题 BZOJ 1052