BZOJ 1052 二分+贪心
想到了一部分,没想全,还是看了题解。。
也不知道为什么对。。。
首先,求出所有点的4个边界值形成的一个矩形,第一个正方形的一个边界一定与这个矩形的4个角中的一个重合,枚举4次即可,
然后再找到剩下的点中的边界,重复一遍上面的操作,最后判断一下一个正方形是否可以覆盖剩余的所有矩形
View Code
1 #include <iostream> 2 #include <cstdio> 3 #include <cstdlib> 4 #include <algorithm> 5 #include <cstring> 6 7 #define N 22222 8 #define INF 2147483647 9 10 using namespace std; 11 /* 12 首先,求出所有点的4个边界值形成的一个矩形,第一个正方形的一个边界一定与这个矩形的4个角中的一个重合,枚举4次即可, 13 然后再找到剩下的点中的边界,重复一遍上面的操作,最后判断一下一个正方形是否可以覆盖剩余的所有矩形 14 */ 15 struct P 16 { 17 int x,y; 18 }p[N],p1[N],p2[N]; 19 20 int n; 21 22 inline void read() 23 { 24 scanf("%d",&n); 25 for(int i=1;i<=n;i++) scanf("%d%d",&p[i].x,&p[i].y); 26 } 27 28 inline bool check(int len) 29 { 30 if(n==0) return true; 31 int sd[4][4]; 32 sd[1][1]=INF; sd[1][2]=-INF; 33 sd[2][1]=INF; sd[2][2]=-INF; 34 for(int i=1;i<=n;i++) 35 { 36 sd[1][1]=min(sd[1][1],p[i].x); sd[1][2]=max(sd[1][2],p[i].x); 37 sd[2][1]=min(sd[2][1],p[i].y); sd[2][2]=max(sd[2][2],p[i].y); 38 } 39 for(int i=1;i<=2;i++) 40 for(int j=1;j<=2;j++) 41 { 42 int m=0; 43 for(int k=1;k<=n;k++) 44 if(abs(p[k].x-sd[1][i])>len||abs(p[k].y-sd[2][j])>len) p1[++m]=p[k]; 45 if(m==0) return true; 46 47 int sp[4][4]; 48 sp[1][1]=INF; sp[1][2]=-INF; 49 sp[2][1]=INF; sp[2][2]=-INF; 50 for(int k=1;k<=m;k++) 51 { 52 sp[1][1]=min(sp[1][1],p1[k].x); sp[1][2]=max(sp[1][2],p1[k].x); 53 sp[2][1]=min(sp[2][1],p1[k].y); sp[2][2]=max(sp[2][2],p1[k].y); 54 } 55 for(int ii=1;ii<=2;ii++) 56 for(int jj=1;jj<=2;jj++) 57 { 58 int s=0; 59 for(int kk=1;kk<=m;kk++) 60 if(abs(p1[kk].x-sp[1][ii])>len||abs(p1[kk].y-sp[2][jj])>len) p2[++s]=p1[kk]; 61 if(s==0) return true; 62 63 int sq[4][4]; 64 sq[1][1]=INF; sq[1][2]=-INF; 65 sq[2][1]=INF; sq[2][2]=-INF; 66 for(int kk=1;kk<=s;kk++) 67 { 68 sq[1][1]=min(sq[1][1],p2[kk].x); sq[1][2]=max(sq[1][2],p2[kk].x); 69 sq[2][1]=min(sq[2][1],p2[kk].y); sq[2][2]=max(sq[2][2],p2[kk].y); 70 } 71 if(sq[2][2]-sq[2][1]<=len&&sq[1][2]-sq[1][1]<=len) return true; 72 } 73 } 74 return false; 75 } 76 77 inline void go() 78 { 79 int l=0,r=2000000000,mid,ans; 80 while(l<=r) 81 { 82 mid=(l+r)>>1; 83 if(check(mid)) ans=mid,r=mid-1; 84 else l=mid+1; 85 } 86 printf("%d\n",ans); 87 } 88 89 int main() 90 { 91 read(),go(); 92 return 0; 93 }
没有人能阻止我前进的步伐,除了我自己!