P2218 [HAOI2007]覆盖问题

题目描述

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

输入输出格式

输入格式:

第一行有一个正整数\(N\),表示有多少棵树。

接下来有\(N\)行,第\(i+1\)行有\(2\)个整数\(X_i\),\(Y_i\),表示第\(i\)棵树的坐标,保证不会有\(2\)个树的坐标相同。

输出格式:

一行,输出最小的\(L\)值。

说明

数据范围

\(100\%\)的数据,\(-1,000,000,000<=X_i,Y_i<=1,000,000,000\)

\(30\%\)的数据,\(N<=100\)

\(50\%\)的数据,\(N<=2000\)

\(100\%\)的数据,\(N<=20000\)


一道思路自然,感觉解法非常有道理但是想不到的题目(其实是我太菜)

二分答案+贪心或枚举放正方形,一般都可以想到这里来

然后怎么放呢。。。

考虑一些看起来非常容易忽视的条件

“\(3\)个\(L*L\)的正方形的边要求平行于坐标轴”

“3个”、“平行于坐标轴”

这是两个关键词

坐标轴是相互垂直的,那么如果我们用一个矩性围住点集,我们惊奇的发现,这个矩形是唯一的。

这里可能是比较跳跃,但是多试多换思路,其实是可能想到的。

然后“3个”正方形,我们发现矩形的每条边都需要和正方形的相接,因为边上必有点需要覆盖

因为矩形有四个边,我们发现有一个正方形必须去填角。

枚举!

然后只有两个正方形,而且剩余点集构成子问题

递归求解!

因为状态数非常少,所以很显然可过

总结一下,没什么思路的时候不妨多分析分析题目条件的特殊性究竟有什么意义,哪怕没什么感觉也多试几个想法


Code:

#include <cstdio>
#include <cstring>
int min(int x,int y){return x<y?x:y;}
int max(int x,int y){return x>y?x:y;}
const int N=20010;
const int inf=0x3f3f3f3f;
int dx[N],dy[N],used[N],l,r,up,down,n;
void get()
{
l=down=inf,r=up=-inf;
for(int i=1;i<=n;i++)
{
if(used[i]) continue;
l=min(l,dx[i]),r=max(r,dx[i]);
down=min(down,dy[i]),up=max(up,dy[i]);
}
}
bool check(int len,int rest)
{
get();
if(rest==1) return len>=max(r-l,up-down);
int l0=l,r0=r,up0=up,down0=down,flag=0,vis[N];
for(int i=1;i<=n;i++) vis[i]=used[i]; for(int i=1;i<=n;i++)
if(dx[i]>=l0&&dy[i]<=up0&&dx[i]<=l0+len&&dy[i]>=up0-len)
used[i]=1;
flag=max(flag,check(len,rest-1)); for(int i=1;i<=n;i++) used[i]=vis[i];
for(int i=1;i<=n;i++)
if(dx[i]>=l0&&dy[i]>=down0&&dx[i]<=l0+len&&dy[i]<=down0+len)
used[i]=1;
flag=max(flag,check(len,rest-1)); for(int i=1;i<=n;i++) used[i]=vis[i];
for(int i=1;i<=n;i++)
if(dx[i]<=r0&&dy[i]<=up0&&dx[i]>=r0-len&&dy[i]>=up0-len)
used[i]=1;
flag=max(flag,check(len,rest-1)); for(int i=1;i<=n;i++) used[i]=vis[i];
for(int i=1;i<=n;i++)
if(dx[i]<=r0&&dy[i]>=down0&&dx[i]>=r0-len&&dy[i]<=down0+len)
used[i]=1;
flag=max(flag,check(len,rest-1));
return flag;
}
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++)
scanf("%d%d",dx+i,dy+i);
get();
int L=1,R=max(r-l,up-down);
while(L<R)
{
int mid=L+R>>1;
memset(used,0,sizeof(used));
if(check(mid,3))
R=mid;
else
L=mid+1;
}
printf("%d\n",L);
return 0;
}

2018.8.10

洛谷 P2218 [HAOI2007]覆盖问题 解题报告的更多相关文章

  1. 洛谷_Cx的故事_解题报告_第四题70

    1.并查集求最小生成树 Code: #include <stdio.h> #include <stdlib.h>   struct node {     long x,y,c; ...

  2. 洛谷 P2317 [HNOI2005]星际贸易 解题报告

    P2317 [HNOI2005]星际贸易 题目描述 输入输出格式 输入格式: 输出格式: 如果可以找到这样的方案,那么输出文件output.txt中包含两个整数X和Y.X表示贸易额,Y表示净利润并且两 ...

  3. 洛谷 P3802 小魔女帕琪 解题报告

    P3802 小魔女帕琪 题目背景 从前有一个聪明的小魔女帕琪,兴趣是狩猎吸血鬼. 帕琪能熟练使用七种属性(金.木.水.火.土.日.月)的魔法,除了能使用这么多种属性魔法外,她还能将两种以上属性组合,从 ...

  4. 洛谷 P2606 [ZJOI2010]排列计数 解题报告

    P2606 [ZJOI2010]排列计数 题目描述 称一个\(1,2,...,N\)的排列\(P_1,P_2...,P_n\)是\(Magic\)的,当且仅当对所以的\(2<=i<=N\) ...

  5. 洛谷1303 A*B Problem 解题报告

    洛谷1303 A*B Problem 本题地址:http://www.luogu.org/problem/show?pid=1303 题目描述 求两数的积. 输入输出格式 输入格式: 两个数 输出格式 ...

  6. 洛谷 P3084 [USACO13OPEN]照片Photo 解题报告

    [USACO13OPEN]照片Photo 题目描述 农夫约翰决定给站在一条线上的\(N(1 \le N \le 200,000)\)头奶牛制作一张全家福照片,\(N\)头奶牛编号\(1\)到\(N\) ...

  7. NOIP2015 D2T3 洛谷2680 BZOJ4326 运输计划 解题报告

    前言:个人认为这是历年NOIP中比较简单的最后一题了,因此将自己的思路与大家分享. 题目大意: 给一棵无根树,给出m条路径.允许将树上的一条边的权值改为0.求m条路径长度最大值的最小值.n,m< ...

  8. 洛谷 P3965 [TJOI2013]循环格 解题报告

    P3965 [TJOI2013]循环格 题目背景 一个循环格就是一个矩阵,其中所有元素为箭头,指向相邻四个格子. 每个元素有一个坐标(行,列),其中左上角元素坐标为\((0,0)\).给定一个起始位\ ...

  9. 洛谷 P2765 魔术球问题 解题报告

    P2765 魔术球问题 题目描述 问题描述: 假设有\(n\)根柱子,现要按下述规则在这\(n\)根柱子中依次放入编号为\(1,2,3,\dots\)的球. \((1)\) 每次只能在某根柱子的最上面 ...

随机推荐

  1. Apache Maven(三):POM

    什么是 POM? POM (Project Object Model) 项目对象模型.它是一个XML文件,其中包含有关Maven用于构建项目的项目和配置细节的信息.它包含大多数项目的默认值.例如,构建 ...

  2. 第五课:PHP echo和print 语句

    PHP  echo 和 print 语句 PHP 是通过 print 和 echo 语句来动态输出 HTML 内容,虽然 print 和 echo 语句两者的功能几乎是完全一样,但是还是有一点差别的. ...

  3. ko绑定----记录

    1.绑定变量 globalData = ko.observable({item:{}}); 2.绑定html ko.applyBindings(globalData, document.getElem ...

  4. python系列7进程线程和协程

    目录 进程 线程 协程  上下文切换 前言:线程和进程的关系图 由下图可知,在每个应用程序执行的过程中,都会去产生一个主进程和主线程来完成工作,当我们需要并发的执行的时候,就会通过主进程去生成一系列的 ...

  5. Nodejs模块初始化

    模块初始化 一个模块中的JS代码仅在模块第一次被使用时执行一次,并在执行过程中初始化模块的导出对象.之后,缓存起来的导出对象被重复利用. 主模块 通过命令行参数传递给NodeJS以启动程序的模块被称为 ...

  6. R语言学习笔记(十):零碎知识点(21-25)

    21--assign() assign函数可以通过变量名的字符串来赋值 > assign('a', 1:3) > a [1] 1 2 3 > b <- c('a') > ...

  7. Java——static关键字---18.09.27

    static表示“全局”或者“静态”的意思,用来修饰成员变量和成员方法,也可以形成静态static代码块,但在Java语言中没有全局变量的概念. static关键字主要有两种作用: 一.为某特定数据类 ...

  8. JAVA中堆栈和内存分配详解(摘抄)

    在Java中,有六个不同的地方可以存储数据: 1.寄存器:最快的存储区, 由编译器根据需求进行分配,我们在程序中无法控制. 2. 栈:存放基本类型的变量数据和对象的引用,但对象本身不存放在栈中,而是存 ...

  9. Notepad++删除空行的多种实现办法

    Notepad++支持基础的正则表达式,同时由于自身丰富的插件和功能,所以删除空行或有空格的空行,有多种实现办法,条条大路通罗马,闪电博客抛砖引玉,供大家参考. 一.删除空行(不包括有空格类符号的空行 ...

  10. python3.6 新特性学习

    #支持类型提示 typing { def greeting(name: str) -> str: return 'Hello ' + name #在函数greeting中,参数名称的类型为str ...