BZOJ 1052 覆盖问题
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
0 1
0 -1
1 0
-1 0
Sample Output
HINT
首先可以确定此题满足可二分性,明显可以二分答案。所以我们只要能够在线性时间内检验即可了。
线性检测我们可以贪心解决,我们将每次还未被覆盖的点用一个最小的矩形来覆盖,然后每次选择用正方形覆盖它的四个角,总共递归三层,64种情况。所以我们枚举这64种情况,看是否能有一种能够覆盖所有的点。
这个贪心我开始没想到,现在也不会证明(理性想想是对的),我开始想的取左下角的点(x优先)为正方形左下角wa了,然后左下角的点(y优先)为正方形左下角wa了,再最左最下的两条平行坐标轴线的交点为正方形左下角还是wa了。最后将三者综合起来,还是wa了,但是正确率高了一些。这启发我以后贪心可以综合起来,取最优解正确率会高很多。
#include<vector>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cstdlib>
using namespace std; #define inf (1<<29)
#define maxn 20010
int n,x[maxn],y[maxn]; bool exist[maxn]; inline bool dfs(int L,int step,int all)
{
if (all == n) return true;
if (step > ) return false;
int up = -inf,down = inf,le = inf,ri = -inf;
for (int i = ;i <= n;++i)
if (!exist[i])
{
up = max(y[i],up),down = min(y[i],down);
ri = max(x[i],ri),le = min(x[i],le);
}
int inc,nl,nr,nu,nd; vector <int> vec;
inc = ; nl = le,nr = le+L,nu = up,nd = up-L;
for (int i = ;i <= n;++i)
if (!exist[i] && x[i] >= nl&&x[i] <= nr&&y[i] >= nd&&y[i] <= nu)
++inc,exist[i] = true,vec.push_back(i);
if (dfs(L,step+,all+inc)) return true;
for (int i = ;i < vec.size();++i) exist[vec[i]] = false; vec.clear();
inc = ; nl = le,nr = le+L,nu = down+L,nd = down;
for (int i = ;i <= n;++i)
if (!exist[i] && x[i] >= nl&&x[i] <= nr&&y[i] >= nd&&y[i] <= nu)
++inc,exist[i] = true,vec.push_back(i);
if (dfs(L,step+,all+inc)) return true;
for (int i = ;i < vec.size();++i) exist[vec[i]] = false; vec.clear();
inc = ; nl = ri-L,nr = ri,nu = up,nd = up-L;
for (int i = ;i <= n;++i)
if (!exist[i] && x[i] >= nl&&x[i] <= nr&&y[i] >= nd&&y[i] <= nu)
++inc,exist[i] = true,vec.push_back(i);
if (dfs(L,step+,all+inc)) return true;
for (int i = ;i < vec.size();++i) exist[vec[i]] = false; vec.clear();
inc = ; nl = ri-L,nr = ri,nu = down+L,nd = down;
for (int i = ;i <= n;++i)
if (!exist[i] && x[i] >= nl&&x[i] <= nr&&y[i] >= nd&&y[i] <= nu)
++inc,exist[i] = true,vec.push_back(i);
if (dfs(L,step+,all+inc)) return true;
for (int i = ;i < vec.size();++i) exist[vec[i]] = false; vec.clear();
return false;
} inline bool okay(int L)
{
memset(exist,false,n+);
return dfs(L,,);
} int main()
{
freopen("1052.in","r",stdin);
freopen("1052.out","w",stdout);
scanf("%d",&n); for (int i = ;i <= n;++i) scanf("%d %d",&x[i],&y[i]);
if (okay()) printf(""),exit();
int l = ,r = inf,mid;
while (l <= r)
{
mid = (l + r) >> ;
if (okay(mid)) r = mid - ;
else l = mid + ;
}
printf("%d",l);
fclose(stdin); fclose(stdout);
return ;
}
BZOJ 1052 覆盖问题的更多相关文章
- [BZOJ]1052 覆盖问题(HAOI2007)
三矩形覆盖问题啊……不过听说FJOI还出过双圆覆盖问题? Description 某人在山上种了N棵小树苗.冬天来了,温度急速下降,小树苗脆弱得不堪一击,于是树主人想用一些塑料薄膜把这些小树遮盖起来, ...
- BZOJ 1052: [HAOI2007]覆盖问题
BZOJ 1052: [HAOI2007]覆盖问题 题意:给定平面上横纵坐标在-1e9~1e9内的20000个整数点的坐标,用三个大小相同边平行于坐标轴的正方形覆盖(在边界上的也算),问正方形的边长最 ...
- 二分判定 覆盖问题 BZOJ 1052
//二分判定 覆盖问题 BZOJ 1052 // 首先确定一个最小矩阵包围所有点,则最优正方形的一个角一定与矩形一个角重合. // 然后枚举每个角,再解决子问题 #include <bits/s ...
- 【BZOJ 1052】 1052: [HAOI2007]覆盖问题 (乱搞)
1052: [HAOI2007]覆盖问题 Description 某人在山上种了N棵小树苗.冬天来了,温度急速下降,小树苗脆弱得不堪一击,于是树主人想用一些塑料薄 膜把这些小树遮盖起来,经过一番长久的 ...
- AC日记——[HAOI2007]覆盖问题 bzoj 1052
1052 思路: 二分答案: 二分可能的长度: 然后递归判断长度是否可行: 先求出刚好覆盖所有点的矩形: 可行的第一个正方形在矩形的一个角上: 枚举四个角上的正方形,然后删去点: 删去一个正方形后,递 ...
- [BZOJ 1052][HAOI2007]覆盖问题(二分答案)
题目:http://www.lydsy.com:808/JudgeOnline/problem.php?id=1052 分析: 挺有想法的一道题,先二分答案ans,主要是判断的问题. 首先可以弄出把所 ...
- BZOJ 1052 HAOI2007 覆盖问题 二分法答案+DFS
标题效果:特定n点.涵盖所有的点与同方三面.斧头要求方垂直边界,最小平方的需求方长值 最大值至少.答案是很明显的二分法 但验证是一个问题 考虑仅仅有三个正方形,故用一个最小矩形覆盖这三个正方形时至少有 ...
- 【以前的空间】bzoj 1052 [HAOI2007]覆盖问题
这道题的思路挺简单的……就是可以证明如果要覆盖一个区域内的点,那么一定有一个正方形在这“区域内的点所围成的最大矩形的四个角中的一个”(不要吐槽很多的“的”……),对于长度r是否可以覆盖整个区域内的点, ...
- bzoj 1052 dfs
首先可以二分答案,将最优性问题转化为判定性问题. 对于二分到的边长,我们可以把所有的点看成一个大的矩形,这个矩形为包括所有点的最小矩形,那么贪心的想,3个正方形,第一个肯定放在这个矩形其中的一角,然后 ...
随机推荐
- linux ----Inode的结构图
http://www.ruanyifeng.com/blog/2011/12/inode.html 先看看Inode的结构图 再来了解一下文件系统如何存取文件的 1.根据文件名 ...
- Qt 学习之路 :Repeater
前面的章节我们介绍过模型视图.这是一种数据和显示相分离的技术,在 Qt 中有着非常重要的地位.在 QtQuick 中,数据和显示的分离同样也是利用这种“模型-视图”技术实现的.对于每一个视图,数据元素 ...
- Hive数据导入
可以通过多种方式将数据导入hive表 1.通过外部表导入 用户在hive上建external表,建表的同时指定hdfs路径,在数据拷贝到指定hdfs路径的同时,也同时完成数据插入external表. ...
- 全面分析 Spring 的编程式事务管理及声明式事务管理--转
开始之前 关于本教程 本教程将深入讲解 Spring 简单而强大的事务管理功能,包括编程式事务和声明式事务.通过对本教程的学习,您将能够理解 Spring 事务管理的本质,并灵活运用之. 先决条件 本 ...
- Linux - CentOS6.5服务器搭建与初始化配置详解(上)
1.新建一个虚拟机 选择典型 单机下一步 p.MsoNormal,li.MsoNormal,div.MsoNormal { margin: 0cm 0cm 0.0001pt; text-align: ...
- python字符串跟整型互转
print ("整型:",int(50))a=int(50)print("整型:",a)numStr = "50";print (" ...
- html 新元素
html5新元素 html5语义元素 <header> 定义了文档或者文档的一部分区域的页眉 <nav> 定义了导航链接的部分 <section> 定义了文档的某个 ...
- java可变参数Varargs
http://www.cnblogs.com/shishm/archive/2012/01/31/2332656.html J2SE 1.5提供了“Varargs”机制.借助这一机制,可以定义能和多个 ...
- jquery ui 插件------------------------->sortable
<!doctype html><html lang="en"><head> <meta charset="utf-8" ...
- 十三、C# 事件
1.多播委托 2.事件 3.自定义事件 在上一章中,所有委托都只支持单一回调. 然而,一个委托变量可以引用一系列委托,在这一系列委托中,每个委托都顺序指向一个后续的委托, 从而形成了一个委托链,或 ...