「二分答案 + 搜索」[HAOI2007]覆盖问题

[HAOI2007]覆盖问题

题目链接:[HAOI2007]覆盖问题

题目大意

给你\(n\)个坐标,再给你3个\(l \times l\)的矩阵,让你用这些矩阵去包含这些点,要求是将所有点都包含,我们要求\(l\)的最小值

题目题解

想到二分了,不过没想到怎么爆搜

看了下题解,妙啊妙啊,牛逼

每次二分一个 \(l\) 值作为我们想要的矩阵边长,然后由树的坐标我们可能可以找到比原平面直角坐标系更小的一个坐标系,我们在新的坐标系上进行操作就可以了,但怎么进行操作呢?我们如果想尽可能的缩小新坐标系的大小,我们就得让新坐标系上代表四角坐标的树苗被覆盖,这里就得注意,我们只有3个矩阵,想要尽可能的缩小坐标的大小,就得让前两个矩阵尽可能的落在四角上,然后最后再通过新坐标系的四角,判断最后一个矩阵能否覆盖其所有树苗。

怎么找?爆搜啊!

代码如下 (写了半天没写出来,看了下题解发现,woc 我太菜了Orz)

//#define fre yes

#include <cstdio>
#include <cstring>
#include <iostream>

const int N = 20005;
struct Tree{
    int x, y;
} l[N];
int Vis[N];

int n;

void cover(int lx, int rx, int ly, int ry, int id) {
    for (int i = 1; i <= n; i++) {
        if(!Vis[i] && lx <= l[i].x && rx >= l[i].x && ry >= l[i].y && ly <= l[i].y) {
            Vis[i] = id;
        }
    }
}

void recover(int id) {
    for (int i = 1; i <= n; i++) {
        if(Vis[i] == id) Vis[i] = 0;
    }
}

bool dfs(int tot, int k) {
    int lx = 2e9, rx = -2e9, ly = 2e9, ry = -2e9;
    for (int i = 1; i <= n; i++) {
        if(!Vis[i]) {
            lx = std::min(lx, l[i].x);
            rx = std::max(rx, l[i].x);
            ly = std::min(ly, l[i].y);
            ry = std::max(ry, l[i].y);
        }
    }

    if(std::max(rx - lx, ry - ly) <= k) return true;
    if(tot == 3) return false;

    cover(lx, lx + k, ly, ly + k, tot);
    if(dfs(tot + 1, k)) return true;
    recover(tot);
    cover(lx, lx + k, ry - k, ry, tot);
    if(dfs(tot + 1, k)) return true;
    recover(tot);
    cover(rx - k, rx, ly, ly + k, tot);
    if(dfs(tot + 1, k)) return true;
    recover(tot);
    cover(rx - k, rx, ry - k, ry, tot);
    if(dfs(tot + 1, k)) return true;
    recover(tot);
    return false;
}

bool check(int prv) {
    memset(Vis, 0, sizeof(Vis));
    return dfs(1, prv);
}

int main() {
    scanf("%d", &n);
    for (int i = 1; i <= n; i++) {
        scanf("%d %d", &l[i].x, &l[i].y);
    }

    int l = 0, r = 2e9;
    while(l < r) {
        int mid = (l + r) >> 1;
        if(check(mid)) r = mid;
        else l = mid + 1;
    } printf("%d\n", l);
    return 0;
}

原文地址:https://www.cnblogs.com/Nicoppa/p/11511880.html

时间: 2024-11-09 08:03:08

「二分答案 + 搜索」[HAOI2007]覆盖问题的相关文章

bzoj1082: [SCOI2005]栅栏(二分答案搜索判断)

1082: [SCOI2005]栅栏 题目:传送门 题解: 是不是一开始在想DP?本蒟蒻也是qwq,结果很nice的错了ORZ 正解:二分+搜索 我们可以先把两种木材都进行排序,那么如果需要的最大木材比可提供的最大木材还要大的话,那么可以直接舍弃这种需要的木材. 然后就可以进入二分,如果当前可以做贡献的提供木材加起来都没有前mid块需要木材大的话,很明显当前mid不ok 返回判断值再记录答案就好了,注意一些小细节的优化 代码: 1 #include<cstdio> 2 #include<

LibreOJ #2006. 「SCOI2015」小凸玩矩阵 二分答案+二分匹配

#2006. 「SCOI2015」小凸玩矩阵 内存限制:256 MiB时间限制:1000 ms标准输入输出 题目类型:传统评测方式:文本比较 上传者: 匿名 提交提交记录统计讨论测试数据 题目描述 小凸和小方是好朋友,小方给小凸一个 N×M N \times MN×M(N≤M N \leq MN≤M)的矩阵 A AA,要求小凸从其中选出 N NN 个数,其中任意两个数字不能在同一行或同一列,现小凸想知道选出来的 N NN 个数中第 K KK 大的数字的最小值是多少. 输入格式 第一行给出三个整数

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

题目大意:给定n个点,用三个边长相同的正方形覆盖所有点,要求正方形边界与坐标轴垂直,求正方形边长的最小值 最大值最小,很明显二分答案 但是验证是个问题 考虑只有三个正方形,故用一个最小矩形覆盖这三个正方形时至少有一个在角上 若有四个正方形该结论不成立 于是我们采用DFS的方式 每次用一个最小的矩形覆盖所有的点,枚举矩形的四个角 将正方形填进去 由于最大深度是3,所以时间上完全可以承受 #include<cstdio> #include<cstring> #include<io

「CodePlus 2017 11 月赛」汀博尔 (二分答案)

题目链接:https://loj.ac/problem/6249 题意:有 n 棵树,初始时每棵树的高度为 H?i?,第 i 棵树每月都会长高 A?i??.现在有个木料长度总量为 S 的订单,客户要求每块木料的长度不能小于 L,而且木料必须是整棵树(即不能为树的一部分). 现在问你最少需要等多少个月才能满足订单.(数据范围:1<=n<=200000,1<=S,L<=1e18,1<=Hi,Ai<=1e9) 题解:很显然二分答案.上界不能直接选择1e18,会爆long lo

cogs 2652. 秘术「天文密葬法」(0/1分数规划 长链剖分 二分答案 dp

http://cogs.pro:8080/cogs/problem/problem.php?pid=vSXNiVegV 题意:给个树,第i个点有两个权值ai和bi,现在求一条长度为m的路径,使得Σai/Σbi最小. 思路:二分答案得p,把每个点权值变成ai-p*bi,看是否存在长为一条长为m的路使总和<=0. tag数组表示从当前位置沿最长链走到底的值,dp数组初值表示从当前位置的重儿子走到底的值(加负号),用tag[...]+dp[..]维护从当前节点往下走若干步得到的最小值(只更新dp数组

LiberOJ 6003. 「网络流 24 题」魔术球 贪心或者最小路径覆盖

6003. 「网络流 24 题」魔术球 内存限制:256 MiB时间限制:1000 ms标准输入输出 题目类型:传统评测方式:Special Judge 上传者: 匿名 提交提交记录统计讨论测试数据 题目描述 假设有 n nn 根柱子,现要按下述规则在这 n nn 根柱子中依次放入编号为 1,2,3,4,? 1, 2, 3, 4, \cdots1,2,3,4,? 的球. 每次只能在某根柱子的最上面放球. 在同一根柱子中,任何 2 22 个相邻球的编号之和为完全平方数. 试设计一个算法,计算出在 

bzoj1052 覆盖问题 二分答案 dfs

链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1052 题意:找到一个最小边长,使得以此为边长$3$个正方形可以覆盖平面上给定的一些点. 华丽爆零-- 首先看到最小果断想二分答案-- 然后我们证明一个东西-- 首先,根据鸽巢原理,$3$个正方形覆盖由所有点构成的最小矩形一定有一个正方形是压着至少两条边的-- 然后不外乎两种情况-- 1.压的是对边,那么每个都在压对边,有一个正方形会压到三条边,就会压到一个角-- 2.压的是邻边,一定会压到一

loj #535. 「LibreOJ Round #6」花火 树状数组求逆序对+主席树二维数点+整体二分

$ \color{#0066ff}{ 题目描述 }$ 「Hanabi, hanabi--」 一听说祭典上没有烟火,Karen 一脸沮丧. 「有的哦-- 虽然比不上大型烟花就是了.」 还好 Shinobu 早有准备,Alice.Ayaya.Karen.Shinobu.Yoko 五人又能继续愉快地玩耍啦! 「噢--!不是有放上天的烟花嘛!」Karen 兴奋地喊道. 「啊等等--」Yoko 惊呼.Karen 手持点燃引信的烟花,「嗯??」 Yoko 最希望见到的是排列优美的烟火,当然不会放过这个机会-

LiberOJ #6002. 「网络流 24 题」最小路径覆盖

#6002. 「网络流 24 题」最小路径覆盖 内存限制:256 MiB时间限制:1000 ms标准输入输出 题目类型:传统评测方式:Special Judge 上传者: 匿名 提交提交记录统计讨论测试数据 题目描述 给定有向图 G=(V,E) G = (V, E)G=(V,E).设 P PP 是 G GG 的一个简单路(顶点不相交)的集合.如果 V VV 中每个顶点恰好在 P PP 的一条路上,则称 P PP 是 G GG 的一个路径覆盖.P PP 中路径可以从 V VV 的任何一个顶点开始,