[BZOJ]1052 覆盖问题(HAOI2007)
三矩形覆盖问题啊……不过听说FJOI还出过双圆覆盖问题?
Description
Input
Output
一行,输出最小的L值。
Sample Input
4
0 1
0 -1
1 0
-1 0
Sample Output
1
HINT
1 <= N <= 20000,坐标绝对值 <= 10^9,保证不会有2棵树的坐标相同。
Solution
三正方形有些复杂,我们不如先从单正方形,双正方形入手。单正方形的答案就是max(横坐标极差,纵坐标极差)。
双正方形不好贪心,所以我们二分一下答案,判断两个正方形能否覆盖所有点。
我们就思考一下,这两个正方形放在哪里,才能尽量覆盖所有点。
发现覆盖的形式不外乎两种情况,一种是 一个在左上一个在右下 ,另一种是 一个在右上一个在左下。
假设是 一个在左上一个在右下 的情况,处于左上方的正方形一定要盖住横坐标最左的和纵坐标最上的点,因为另一个正方形不会帮你干这件事。
同理,处于右下方的正方形也一样。
所以,两个正方形放置的位置也就确定了,剩下的事情就是O(n)扫一遍判断是否在正方形内了。
那么三正方形其实也是极其类似的做法。
还是二分答案,考虑三个正方形的放法,发现情况有一点多。
但是有一点一定是不变的,那就是必定有一个正方形,处于左上、右上、左下、右下的其中一个角!
那么我们就枚举这个角,删去这个角内的点,剩下的,就是一个双正方形覆盖问题!
时间复杂度O(nlogn)。
#include <cstdio>
#include <algorithm>
#include <cstring>
#define MN 20005
#define INF 0x3FFFFFFF
using namespace std;
struct node{int x,y;}a[MN];
int b[MN];
int bin,n,L,R; inline int read()
{
int n=,f=; char c=getchar();
while (c<'' || c>'') {if(c=='-')f=-; c=getchar();}
while (c>='' && c<='') {n=n*+c-''; c=getchar();}
return n*f;
} bool cov(int len)
{
if (!bin) return true;
register int i,lm,rm,dm,um;
lm=dm=INF; rm=um=-INF;
for (i=;i<=bin;++i)
lm=min(lm,a[b[i]].x),rm=max(rm,a[b[i]].x),
dm=min(dm,a[b[i]].y),um=max(um,a[b[i]].y);
for (i=;i<=bin;++i)
if (!(a[b[i]].x<=lm+len&&a[b[i]].y<=dm+len
||a[b[i]].x>=rm-len&&a[b[i]].y>=um-len)) break;
if (i>bin) return true;
for (i=;i<=bin;++i)
if (!(a[b[i]].x<=lm+len&&a[b[i]].y>=um-len
||a[b[i]].x>=rm-len&&a[b[i]].y<=dm+len)) break;
if (i>bin) return true;
return false;
} void del(int lm,int dm,int rm,int um)
{
register int i;
for (bin=,i=;i<=n;++i)
if (a[i].x<lm||a[i].x>rm||a[i].y<dm||a[i].y>um) b[++bin]=i;
} int main()
{
register int i,lm,rm,dm,um;
lm=dm=INF; rm=um=-INF;
n=read();
for (i=;i<=n;++i)
a[i].x=read(),a[i].y=read(),
lm=min(lm,a[i].x),rm=max(rm,a[i].x),
dm=min(dm,a[i].y),um=max(um,a[i].y);
L=; R=max(um-dm,rm-lm);
while (L<R)
{
int mid=L+R>>;
for (i=;i<=;++i)
{
if (i==) del(lm,dm,lm+mid,dm+mid);
else if (i==) del(lm,um-mid,lm+mid,um);
else if (i==) del(rm-mid,dm,rm,dm+mid);
else if (i==) del(rm-mid,um-mid,rm,um);
if (cov(mid)) break;
}
if (i<=) R=mid; else L=mid+;
}
printf("%d",L);
}
Last Word
没有想到小C能抢到这题的一个rank1,先放张图留念,指不定哪天就被某大神艹下去了。

[BZOJ]1052 覆盖问题(HAOI2007)的更多相关文章
- BZOJ 1052 覆盖问题
Description 某人在山上种了N棵小树苗.冬天来了,温度急速下降,小树苗脆弱得不堪一击,于是树主人想用一些塑料薄膜把这些小树遮盖起来,经过一番长久的思考,他决定用3个L*L的正方形塑料薄膜将小 ...
- 【BZOJ】【1052】【HAOI2007】覆盖问题
二分+贪心 首先二分L,转化成判定问题…… 但是判定不会判啊QAQ orz hzwer,用一个最小的矩形框住所有点后,直接往矩形的角上摆正方形……第二个用同样的方法摆,最后判一下剩下的能否被完全覆盖 ...
- 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是否可以覆盖整个区域内的点, ...
随机推荐
- Python处理图片缩略图
CPU 密集型任务和 IO 密集型任务分别选择多进程multiprocessing.Pool.map 和多线程库multiprocessing.dummy.Pool.map import os imp ...
- 关于java中的数组
前言:最近刚刚看完了<Java编程思想>中关于数组的一章,所有关于Java数组的知识,应该算是了解的差不多了.在此再梳理一遍,以便以后遇到模糊的知识,方便查阅. Java中持有对象的方式, ...
- [Android FrameWork 6.0源码学习] View的重绘过程之WindowManager的addView方法
博客首页:http://www.cnblogs.com/kezhuang/p/关于Activity的contentView的构建过程,我在我的博客中已经分析过了,不了解的可以去看一下<[Andr ...
- vue 保留两位小数 不能直接用toFixed(2) ?
用vue做项目的时候多多少少都会遇到这个问题 刚开始我是用toFixed()这个方法来写的 效果是有的 但是控制台一直是红红的围绕着我 突然想到 vue和jquery混搭 的 问题 于是乎 看了一下 ...
- python小练习之二
title: python小练习之二 tags: 新建,模板,小书匠 grammar_cjkRuby: true --- python小练习之二 需求:实现用户登录,用户名和密码保存到文件里,连续输入 ...
- 看漫画学Flux
原文地址:A cartoon guide to Flux - by Lin Clark Flux在目前web开发中最受欢迎也较不被人理解,本文会以简单易懂的方式解释它. 出现问题 首先,我要声明Flu ...
- New UWP Community Toolkit - DeveloperTools
概述 UWP Community Toolkit 中有一个开发者工具集 DeveloperTools,可以帮助开发者在开发过程中进行 UI 和功能的调试,本篇我们结合代码详细讲解 Develope ...
- Linux知识积累(5) 关机shutdown和重启reboot
Linux centos关机与重启命令详解与实战 Linux centos重启命令: 1.reboot 2.shutdown -r now 立刻重启(root用户使用) 3.shutdown -r 1 ...
- linux下git常用命令
1 安装: sudo apt-get install git 2 创建一个版本库: 新建一个文件夹,进入这个目录之后 git init 3 创建一个版本: git add 文件名或目录 #表示将当前文 ...
- Python之进程
进程 进程(Process)是计算机中的程序关于某数据集合上的一次运行活动,是系统进行资源分配和调度的基本单位,是操作系统结构的基础.在早期面向进程设计的计算机结构中,进程是程序的基本执行实体:在当代 ...