当前位置: 首页 > news >正文

LuoguP2218 [HAOI2007] 覆盖问题 题解

前言

题目传送门 P2218 [HAOI2007] 覆盖问题

题意简述

在一个平面直角坐标系中给定 \(N\) 个点,现在使用三个边长为 \(L\) 正方形将这些点全部覆盖,且正方形的边平行于坐标轴。求 \(L\) 最小值。

思路:二分 + DFS

首先考虑下面的简化问题:使用一个最小矩形覆盖平面直角坐标系内所有点,矩形的边与坐标轴平行,问应该怎么放。这很简单:我们一定能在所有的点中找出最左、最右、最上、最下的四至点,让它们分别位于矩形的四条边上即可。

然后看我们的这个问题。我们需要把刚刚的矩形拆分成三个小正方形,那么显然至少有一个正方形需要覆盖四至点中的两个。并且为了让正方形最小,我们应该用正方形的边去覆盖,并且覆盖一角(如最左和最下)要优于覆盖一条(如最左和最右)。

有了这个思路,我们就可以开始着手写代码了。

先考虑二分部分。答案显然具有单调性:边长越大,能覆盖的点就越多。本题又是经典的最大值最小化模板,就不再赘述。

主要问题是 check() 函数怎么写。按上面的思路,我们按顺序摆放三个正方形:

  • 对于第一个,此时所有的点都未覆盖,我们可以把它摆到任意一个角,所以需要枚举四种情况;

  • 对于第二个,此时在还未覆盖的点中我们需要摆下两个正方形,那么同样放在一角去覆盖两个四至点是最优的。我们找出新的四至点,同上进行枚举。

  • 对于第三个,此时在还未覆盖的点中我们只能放下一个正方形。那么就无所谓优劣了,我们必须保证这最后一个正方形能覆盖所有尚未覆盖的点。那么不用枚举,直接检查边长是否足够即可。

容易看出,上面所说的过程可以用 DFS 实现。于是就可以愉快的打暴搜(bushi DFS 了。

代码

代码如下:

记得开 \(\texttt{long long}\) 哦!

#include<iostream>
#include<cstring>
#define fastio ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
#define int long long
#define MIKU 0
using namespace std;const int INF = 1e18;int n, maxx = -INF, minx = INF, maxy = -INF, miny = INF;
struct Point { int x, y; } P[20005];bool cvd[20005];  //标记点是否被覆盖
void addtag(int l, int r, int d, int u, bool tag) {  //给点加上已覆盖/未覆盖标记for(int i=1; i<=n; i++) {if(P[i].x >= l && P[i].x <= r && P[i].y >= d && P[i].y <= u) cvd[i] = tag;}
}
bool dfs(int k, int x) {int maxx = -INF, minx = INF, maxy = -INF, miny = INF;for(int i=1; i<=n; i++) if(!cvd[i]) {maxx = max(maxx, P[i].x), minx = min(minx, P[i].x);maxy = max(maxy, P[i].y), miny = min(miny, P[i].y);}if(x >= max(maxx-minx, maxy-miny)) return 1;if(k == 3) return 0;  //如果是第三个方形且不满足上面的条件,则边长不足//枚举即可addtag(minx, minx+x, miny, miny+x, 1);if (dfs(k+1, x)) return 1;addtag(minx, minx+x, miny, miny+x, 0);addtag(minx, minx+x, maxy-x, maxy, 1);if (dfs(k+1, x)) return 1;addtag(minx, minx+x, maxy-x, maxy, 0);addtag(maxx-x, maxx, maxy-x, maxy, 1);if (dfs(k+1, x)) return 1;addtag(maxx-x, maxx, maxy-x, maxy, 0);addtag(maxx-x, maxx, miny, miny+x, 1);if (dfs(k+1, x)) return 1;addtag(maxx-x, maxx, miny, miny+x, 0);return 0;
}
bool check(int mid) {memset(cvd, 0, sizeof(cvd));return dfs(1, mid);
} signed main() {fastio;cin>>n;for(int i=1; i<=n; i++) {cin>>P[i].x>>P[i].y;maxx = max(maxx, P[i].x), minx = min(minx, P[i].x);maxy = max(maxy, P[i].y), miny = min(miny, P[i].y);}int l = 0, r = max(maxx-minx, maxy-miny);  //注意上界while(l < r) {int mid = (l + r) >> 1;if(check(mid)) r = mid;else l = mid + 1;}cout<<l;return MIKU;
}
http://www.jsqmd.com/news/377435/

相关文章:

  • P1775 学习笔记
  • 大润发购物卡回收技巧分享 - 团团收购物卡回收
  • 【节点】[BakedGI节点]原理解析与实际应用
  • HSC 电路分析(谐振型)
  • 选购自动锁螺丝机有啥技巧,温州宏海机器人自动锁螺丝机咋样? - 工业品牌热点
  • 芯片设计公司用哪款IM最好?(高保密推荐) - 企业数字化观察家
  • A.每日一题——1446. 连续字符
  • 单通道8孔荧光定量PCR仪
  • 回收大润发购物卡,秒到账! - 团团收购物卡回收
  • 2026年入坑程序员请注意:千万别碰这几个即将被计算机行业淘汰的编程语言!Java/python/golang/C/C++/C#/开发/测试运维/后端/码士集团
  • 【计算机基础】-45-RT-Thread-内存管理机制专注于“运行期堆内存”的动态分配与回收,RT-Thread提供了哪些内存管理机制和算法,以及各自的应用场合。
  • SQL Server Management Studio (SSMS) 22.3.0 - 微软数据库管理工具
  • 2.5 采样策略完全指南:温度、top-p、思维链、结构化输出实战
  • 2.3 模型规模与性能的权衡:参数、上下文、算力全攻略
  • 分期乐购物额度怎么提出来?简单三步快速上手! - 团团收购物卡回收
  • Visual Studio 2026 Enterprise 18.3.0 Offline (2026 年 2 月更新)
  • 2.4 后训练技术:SFT与RLHF从原理到实战
  • 【计算机基础】-46-“用合适的工具做合适的事” —— 通用场景用 Small Memory, 实时关键场景用 不同size的Memory Pool, 内核对象用 Slab, 大内存用 Buddy。
  • ArkUI框架运行原理与常见性能优化方案
  • Apache Cassandra Connector Flink 与宽列存储的高吞吐协作 - 实践
  • 完整教程:【低空经济】低空经济智能制造基地建设方案
  • AI 画图全家桶来了!这回想自己手绘图都难了
  • 专业检测背书,标准引领品质——独语N627-1领跑学生护眼市场 - 资讯焦点
  • setupldr源代码分析之得到SetupDevice和打开文件txtsetup.sif和biosinfo.inf
  • 买中宁枸杞选哪个品牌?玺赞深耕十年,用道地品质筑牢口碑标杆 - 宁夏壹山网络
  • 计算机毕业设计Python+Django微博舆情分析系统 微博舆情预测 微博爬虫 微博大数 据(源码+LW文档+PPT+详细讲解)
  • 【深度解析】某水务集团“十五五“数据资产化战略:构建水务数据资产与水权交易双轮驱动的数字化新生态(WORD)
  • 1.1 从语言模型到LLM:万字详解大模型演进史
  • 洗碗粉(洗碗机清洁剂)市场细分观察:安全、效能与场景驱动的品牌分化
  • 2026选新型高清印刷机定制厂家,这份排行分析别错过,市场高清印刷机怎么选购精选实力品牌 - 品牌推荐师