• 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 }
    没有人能阻止我前进的步伐,除了我自己!
  • 相关阅读:
    luoguP3822 [NOI2017]整数
    luoguP2150 [NOI2015]寿司晚宴
    luoguP3868 [TJOI2009]猜数字
    luoguP4777 【模板】扩展中国剩余定理(EXCRT)
    luoguP2048 超级钢琴
    题解 P1004 【方格取数】
    戊戌年西安游记
    题解 P4388 【付公主的矩形】
    题解 P4277 【河城荷取的烟花】
    001 dynamic Linq
  • 原文地址:https://www.cnblogs.com/proverbs/p/2956827.html
Copyright © 2020-2023  润新知