Description

某人在山上种了N棵小树苗。冬天来了,温度急速下降,小树苗脆弱得不堪一击,于是树主人想用一些塑料薄膜把这些小树遮盖起来,经过一番长久的思考,他决定用3个L*L的正方形塑料薄膜将小树遮起来。我们不妨将山建立一个平面直角坐标系,设第i棵小树的坐标为(Xi,Yi),3个L*L的正方形的边要求平行与坐标轴,一个点如果在正方形的边界上,也算作被覆盖。当然,我们希望塑料薄膜面积越小越好,即求L最小值。

Input

第一行有一个正整数N,表示有多少棵树。接下来有N行,第i+1行有2个整数Xi,Yi,表示第i棵树的坐标,保证不会有2个树的坐标相同。

Output

一行,输出最小的L值。

Sample Input

4
0 1
0 -1
1 0
-1 0

Sample Output

1

HINT

首先可以确定此题满足可二分性,明显可以二分答案。所以我们只要能够在线性时间内检验即可了。

线性检测我们可以贪心解决,我们将每次还未被覆盖的点用一个最小的矩形来覆盖,然后每次选择用正方形覆盖它的四个角,总共递归三层,64种情况。所以我们枚举这64种情况,看是否能有一种能够覆盖所有的点。

这个贪心我开始没想到,现在也不会证明(理性想想是对的),我开始想的取左下角的点(x优先)为正方形左下角wa了,然后左下角的点(y优先)为正方形左下角wa了,再最左最下的两条平行坐标轴线的交点为正方形左下角还是wa了。最后将三者综合起来,还是wa了,但是正确率高了一些。这启发我以后贪心可以综合起来,取最优解正确率会高很多。

  1. #include<vector>
  2. #include<iostream>
  3. #include<cstring>
  4. #include<cstdio>
  5. #include<cstdlib>
  6. using namespace std;
  7.  
  8. #define inf (1<<29)
  9. #define maxn 20010
  10. int n,x[maxn],y[maxn]; bool exist[maxn];
  11.  
  12. inline bool dfs(int L,int step,int all)
  13. {
  14. if (all == n) return true;
  15. if (step > ) return false;
  16. int up = -inf,down = inf,le = inf,ri = -inf;
  17. for (int i = ;i <= n;++i)
  18. if (!exist[i])
  19. {
  20. up = max(y[i],up),down = min(y[i],down);
  21. ri = max(x[i],ri),le = min(x[i],le);
  22. }
  23. int inc,nl,nr,nu,nd; vector <int> vec;
  24. inc = ; nl = le,nr = le+L,nu = up,nd = up-L;
  25. for (int i = ;i <= n;++i)
  26. if (!exist[i] && x[i] >= nl&&x[i] <= nr&&y[i] >= nd&&y[i] <= nu)
  27. ++inc,exist[i] = true,vec.push_back(i);
  28. if (dfs(L,step+,all+inc)) return true;
  29. for (int i = ;i < vec.size();++i) exist[vec[i]] = false; vec.clear();
  30. inc = ; nl = le,nr = le+L,nu = down+L,nd = down;
  31. for (int i = ;i <= n;++i)
  32. if (!exist[i] && x[i] >= nl&&x[i] <= nr&&y[i] >= nd&&y[i] <= nu)
  33. ++inc,exist[i] = true,vec.push_back(i);
  34. if (dfs(L,step+,all+inc)) return true;
  35. for (int i = ;i < vec.size();++i) exist[vec[i]] = false; vec.clear();
  36. inc = ; nl = ri-L,nr = ri,nu = up,nd = up-L;
  37. for (int i = ;i <= n;++i)
  38. if (!exist[i] && x[i] >= nl&&x[i] <= nr&&y[i] >= nd&&y[i] <= nu)
  39. ++inc,exist[i] = true,vec.push_back(i);
  40. if (dfs(L,step+,all+inc)) return true;
  41. for (int i = ;i < vec.size();++i) exist[vec[i]] = false; vec.clear();
  42. inc = ; nl = ri-L,nr = ri,nu = down+L,nd = down;
  43. for (int i = ;i <= n;++i)
  44. if (!exist[i] && x[i] >= nl&&x[i] <= nr&&y[i] >= nd&&y[i] <= nu)
  45. ++inc,exist[i] = true,vec.push_back(i);
  46. if (dfs(L,step+,all+inc)) return true;
  47. for (int i = ;i < vec.size();++i) exist[vec[i]] = false; vec.clear();
  48. return false;
  49. }
  50.  
  51. inline bool okay(int L)
  52. {
  53. memset(exist,false,n+);
  54. return dfs(L,,);
  55. }
  56.  
  57. int main()
  58. {
  59. freopen("1052.in","r",stdin);
  60. freopen("1052.out","w",stdout);
  61. scanf("%d",&n); for (int i = ;i <= n;++i) scanf("%d %d",&x[i],&y[i]);
  62. if (okay()) printf(""),exit();
  63. int l = ,r = inf,mid;
  64. while (l <= r)
  65. {
  66. mid = (l + r) >> ;
  67. if (okay(mid)) r = mid - ;
  68. else l = mid + ;
  69. }
  70. printf("%d",l);
  71. fclose(stdin); fclose(stdout);
  72. return ;
  73. }

BZOJ 1052 覆盖问题的更多相关文章

  1. [BZOJ]1052 覆盖问题(HAOI2007)

    三矩形覆盖问题啊……不过听说FJOI还出过双圆覆盖问题? Description 某人在山上种了N棵小树苗.冬天来了,温度急速下降,小树苗脆弱得不堪一击,于是树主人想用一些塑料薄膜把这些小树遮盖起来, ...

  2. BZOJ 1052: [HAOI2007]覆盖问题

    BZOJ 1052: [HAOI2007]覆盖问题 题意:给定平面上横纵坐标在-1e9~1e9内的20000个整数点的坐标,用三个大小相同边平行于坐标轴的正方形覆盖(在边界上的也算),问正方形的边长最 ...

  3. 二分判定 覆盖问题 BZOJ 1052

    //二分判定 覆盖问题 BZOJ 1052 // 首先确定一个最小矩阵包围所有点,则最优正方形的一个角一定与矩形一个角重合. // 然后枚举每个角,再解决子问题 #include <bits/s ...

  4. 【BZOJ 1052】 1052: [HAOI2007]覆盖问题 (乱搞)

    1052: [HAOI2007]覆盖问题 Description 某人在山上种了N棵小树苗.冬天来了,温度急速下降,小树苗脆弱得不堪一击,于是树主人想用一些塑料薄 膜把这些小树遮盖起来,经过一番长久的 ...

  5. AC日记——[HAOI2007]覆盖问题 bzoj 1052

    1052 思路: 二分答案: 二分可能的长度: 然后递归判断长度是否可行: 先求出刚好覆盖所有点的矩形: 可行的第一个正方形在矩形的一个角上: 枚举四个角上的正方形,然后删去点: 删去一个正方形后,递 ...

  6. [BZOJ 1052][HAOI2007]覆盖问题(二分答案)

    题目:http://www.lydsy.com:808/JudgeOnline/problem.php?id=1052 分析: 挺有想法的一道题,先二分答案ans,主要是判断的问题. 首先可以弄出把所 ...

  7. BZOJ 1052 HAOI2007 覆盖问题 二分法答案+DFS

    标题效果:特定n点.涵盖所有的点与同方三面.斧头要求方垂直边界,最小平方的需求方长值 最大值至少.答案是很明显的二分法 但验证是一个问题 考虑仅仅有三个正方形,故用一个最小矩形覆盖这三个正方形时至少有 ...

  8. 【以前的空间】bzoj 1052 [HAOI2007]覆盖问题

    这道题的思路挺简单的……就是可以证明如果要覆盖一个区域内的点,那么一定有一个正方形在这“区域内的点所围成的最大矩形的四个角中的一个”(不要吐槽很多的“的”……),对于长度r是否可以覆盖整个区域内的点, ...

  9. bzoj 1052 dfs

    首先可以二分答案,将最优性问题转化为判定性问题. 对于二分到的边长,我们可以把所有的点看成一个大的矩形,这个矩形为包括所有点的最小矩形,那么贪心的想,3个正方形,第一个肯定放在这个矩形其中的一角,然后 ...

随机推荐

  1. android 回车键事件编程

    实现android按下回车键便隐藏输入键盘,有两种方法: 1.)如果布局是多个EditText,为每个EditText控件设置android:singleLine=”true”,弹出的软盘输入法中回车 ...

  2. 你需要知道的 Android 拍照适配方案

    近段时间,家里陪自己度过大学四年的电脑坏了,挑选好的新电脑配件终于在本周全部到货,自己动手完成组装.从AMD到i7的CPU,6G内存到14G内存,打开 AndroidStudio 的速度终于杠杆的上去 ...

  3. Programming a Spider in Java 源码帖

    Programming a Spider in Java 源码帖 Listing 1: Finding the bad links (CheckLinks.java) import java.awt. ...

  4. CUDA与VS2013安装

    @import url(http://i.cnblogs.com/Load.ashx?type=style&file=SyntaxHighlighter.css);@import url(/c ...

  5. DataTable和List集合互转

    /// <summary> /// 将集合转换成DataTable /// </summary> /// <param name="list"> ...

  6. [原创] SQLite数据库使用清单(上)

    1. 介绍 1.1 安装 访问 SQLite 下载页面,从 Windows 区下载预编译的二进制文件. 您需要下载 sqlite-shell-win32-*.zip 和 sqlite-dll-win3 ...

  7. Android 4.0及以上版本接收开机广播BOOT_COMPLETED、开机自启动服务

    1.BootCompletedReceiver.Java文件 public class BootCompletedReceiver extends BroadcastReceiver { @Overr ...

  8. VS2015 Cordova Ionic移动开发(五)

    一.创建侧边菜单和导航项目 1.使用VS创建一个Ionic空项目,同时创建一个Ionic SideMenu和Ionic Tabs项目.将SideMenu和Tabs项目里的templates和js文件合 ...

  9. [转帖]音响及DarBee

    红外与蓝牙的差别 1.距离 红外:对准.直接.1—2米,单对单 红外线可以用你的手机摄像头看到  蓝牙:10米左右,可加强信号,可以绕弯,可以不对准,可以不在同一间房间,链接最大数目可达7个,同时区分 ...

  10. oracle安装遇到的问题

    这两天要做一个项目,教师招聘系统.要用oracle.就安装了oracle 12c,安装的过程中遇到了一些问题,最后自己解决了.我是win7系统. 第一个报错: [INS-30131]执行安装程序验证所 ...