首先可以二分答案,将最优性问题转化为判定性问题。

  对于二分到的边长,我们可以把所有的点看成一个大的矩形,这个矩形为包括所有点的最小矩形,那么贪心的想,3个正方形,第一个肯定放在这个矩形其中的一角,然后去掉覆盖的点,然后再求出一个矩形,然后再枚举放在哪一角,去掉之后判断剩下的是否可以由一个正方形覆盖就行了。

  反思:没画图,边界算的不对,而且枚举完两个正方形之后要判下是否没有没覆盖的点了。另外提供神样例 4 1 1 -1 -1 1 -1 -1 1答案是2。

/**************************************************************
    Problem: 1052
    User: BLADEVIL
    Language: C++
    Result: Accepted
    Time:1484 ms
    Memory:1280 kb
****************************************************************/
 
//By BLADEVIL
#include <cstdio>
#include <cstring>
#include <algorithm>
#define maxn 20010
#define inf (~0U>>1)
 
using namespace std;
 
struct rec {
    int x,y,flag;
    rec(){
        x=y=flag=;
    }
}a[maxn],b[maxn];
 
int n;
 
bool cmp(rec x,rec y) {
    return (x.flag<y.flag);
}
 
void update(rec &MAX,rec &MIN) {
    MAX.x=MAX.y=-inf;
    MIN.x=MIN.y=inf;
    for (int i=;(i<=n)&&(!b[i].flag);i++) {
        MAX.x=max(MAX.x,b[i].x);
        MIN.x=min(MIN.x,b[i].x);
        MAX.y=max(MAX.y,b[i].y);
        MIN.y=min(MIN.y,b[i].y);
    }
}
 
void make(int x,int len) {
    rec MAX,MIN;
    update(MAX,MIN);
    //printf("%d %d %d %d\n",MAX.x,MAX.y,MIN.x,MIN.y);
    int up,down,left,right;
    if (x==) {
        up=MAX.y; left=MIN.x;
        down=up-len; right=left+len;
    }
    if (x==) {
        up=MIN.y+len; left=MIN.x;
        right=left+len; down=MIN.y;
    }
    if (x==) {
        right=MAX.x; left=right-len;
        down=MIN.y; up=down+len;
    }
    if (x==) {
        up=MAX.y; down=up-len;
        right=MAX.x; left=right-len;
    }
    //printf("%d %d %d %d %d\n",x,left,right,up,down); 
    for (int i=;i<=n;i++) if ((b[i].x<=right)&&(b[i].x>=left)&&(b[i].y<=up)&&(b[i].y>=down)) b[i].flag=;
}
 
bool work(int i,int j,int x) {
    memcpy(b,a,sizeof a);
    make(i,x);
    sort(b+,b++n,cmp);
    make(j,x);
    sort(b+,b++n,cmp);
    rec MAX,MIN;
    update(MAX,MIN);
    int left=MIN.x,right=MAX.x,up=MAX.y,down=MIN.y;
    //printf("%d %d %d %d %d\n",x,left,right,up,down);
    if ((left==inf)&&(right==-inf)&&(up==-inf)&&(down==inf)) return ;
    if ((MAX.x-MIN.x<=x)&&(MAX.y-MIN.y<=x)) return ; else return ;
}
 
bool judge(int x) {
    for (int i=;i<=;i++)
        for (int j=;j<=;j++) if (i!=j) if (work(i,j,x)) return ;
    return ;
}
 
int main() {
    scanf("%d",&n);
    for (int i=;i<=n;i++) scanf("%d%d",&a[i].x,&a[i].y);
    //printf("%d\n",work(1,2,1)); return 0;
    int l=,r=1e9,ans=;
    while (l<=r) {
        //printf("%d %d\n",l,r);
        int mid=l+r>>;
        if (judge(mid)) ans=mid,r=mid-; else l=mid+;
    }
    printf("%d\n",ans);
    return ;
}

最新文章

  1. CDH集群主节点宕机恢复
  2. 三、最小化的Spring XML配置
  3. Android 中算法问题
  4. datetime与smalldatetime之间的区别
  5. paper 68 :MATLAB中取整函数(fix, floor, ceil, round)的使用
  6. QListWidget代码刷新界面
  7. 002.TPerlRegEx简单测试
  8. 【SPOJ 2319】 BIGSEQ - Sequence (数位DP+高精度)
  9. nodejs 如何使用upgrade,并且C/B 发送消息
  10. akoj-1280另类阶乘问题
  11. 基于Oracle ADF的应用程序开发
  12. jQuery实现Ajax请求时,页面显示等待的效果,超过指定请求时间后,进行其他操作
  13. node-sass下载失败 关于webpack
  14. Java 8新特性之 Base64(八恶人-7)
  15. Css预处理器---Less(二)
  16. Linux free -m 详解命令
  17. 尼克的任务(P1280)
  18. MS SQL backup database的俩个参数
  19. K8S钩子操作
  20. PS基础教程[1]如何制作微信泡泡

热门文章

  1. week1技术随笔
  2. animate.css与wow.js制作网站动效
  3. try catch finally 与continue的使用
  4. WITH REPLACE 含义
  5. Spring事务管理Transaction
  6. BZOJ 1509 逃学的小孩(树的直径)
  7. BZOJ 1057 棋盘制作(最大01相间子矩阵)
  8. Qt——树结点的搜索
  9. Selector 模型
  10. Android Canvas 绘图