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 }
没有人能阻止我前进的步伐,除了我自己!
原文地址:https://www.cnblogs.com/proverbs/p/2956827.html