管道(acwing,蓝桥杯,二分)

题目描述:

有一根长度为 len 的横向的管道,该管道按照单位长度分为 len 段,每一段的中央有一个可开关的阀门和一个检测水流的传感器。

一开始管道是空的,位于 Li的阀门会在 Si 时刻打开,并不断让水流入管道。

对于位于 Li的阀门,它流入的水在 Ti(Ti≥Si)时刻会使得从第 Li−(Ti−Si) 段到第 Li+(Ti−Si)段的传感器检测到水流。

求管道中每一段中间的传感器都检测到有水流的最早时间。

输入格式:

输入的第一行包含两个整数 n,len,用一个空格分隔,分别表示会打开的阀门数和管道长度。

接下来 n行每行包含两个整数 Li,Si,用一个空格分隔,表示位于第 Li 段管道中央的阀门会在 Si 时刻打开。

输出格式:

输出一行包含一个整数表示答案。

数据范围:

对于 30%的评测用例,n≤200,Si,len≤3000;
对于 70%的评测用例,n≤5000,Si,len≤1e5;
对于所有评测用例,1≤n≤1e5,1≤Si,len≤1e9,1≤Li≤len,Li−1<Li。

输入样例:

3 10
1 1
6 5
10 2

输出样例:

5

分析步骤:

  第一:我们拿到这道题我们可以看到,是一段管道里有许多的水龙头,当开启不同水龙头的时候它可以向两边扩散速度是:1段/s。不同水龙头控制的区域也不一样,至此我们分析出了第一个特点有区间问题,需要合并看看有没有全部覆盖管道

            我们还可以发现当时间开的越长,管道内有水的区域也越长,这呈现一种单调的特点,并且我们可以求出一个时间点,在这个时间点的左边管道内不能全部都流过水,在这个时间点和以后都可以覆盖全管道。至此也满足了二分的特点

            所以本题要运用二分+区间合并来做;

 

第二:知道了考的知识点,咱们就要书写主函数,把握整体框架。

           首先把值都输入进去,其次开始二分

            定义我们的左节点 l 为 0 因为有可能水管从第零分钟就一直开着,并且每个管道段落都有水龙头,所以最小时间可能是 0

             定义右节点 r 为 2e9 .因为题目说了 Si 最大为 1e9  所以有可能在最后一秒也就是1e9秒时 ,开启开关并且只有一个开关且在第一个管道之内,所以要覆盖管道又要1e9s 所以两个 1e9 相加就是 2e9。

           求出mid,再判断一下这个 mid 的值

            如果是对的,则证明比 mid 的时间大小更大的值就更可以覆盖满管道.因为假如 mid 为5秒时已经覆盖了管道,那么6秒更会是管道内充水。所以应该将 mid 赋值给 r

            如果 mid 的时间大小不可以,那么比mid还小的话更是不可能覆盖的了管道了。所以应该将 mid + 1 的值 赋值给 l;

int main()
{
    cin>>n>>m;
    for(int i = 0 ; i < n ; i ++){
        cin>>q[i].x>>q[i].y;
    }
    LL l = 0 , r = 2e9;
    while(l<r){
        LL mid = (l+r) / 2;
        if(check(mid)) r = mid;
        else l = mid + 1;
    }
    cout<<r;
    return 0;
}

  第三:书写 check 函数定义一个 计数器 cnt 用一个f or 循环将之前存储的数据取出来,如果mid这个时间大于了我们的S这个时间的话,那么就意味着这个开关已经开启了并且流出了一段的水,这段时间的差值 就是这个开关向左右两边扩散的距离,所以我们用 t 计算出这段时间差。

          确定左右区间:

           我们接下来看这个开关可以控制的区间范围因为 t 就是扩散的距离 所以我们的 int l = max(1, L-t ) ,左边界范围就是第 L 个开关向左走了 t 时间的路 和 1 取最大值进行动态更新

            r = min((LL)m,(LL)L+t);右边界范围就是第 L 个开关向左走了 t 时间的路 和 m 取最小值进行动态更新因为不可以超过管道长度。

            最后将这个开关的区间边界放入 p 数组之中;至此我们区间范围已然确定。

int cnt = 0 ; 
     for(int i = 0 ; i < n ; i ++){
         int L = q[i].x , S = q[i].y;
         if(mid >= S){
             int t = mid - S;
             int l = max(1,L-t) , r = min((LL)m,(LL)L+t);
                  p[cnt++]={l,r};
         }
     }

  第四:接下来进行区间合并。我们先进行sort排序这样这些区间的左端点就可以从小到大排序,我们就只要比较右端点就行。

           我们定义左端点 st 为 -1 ; 右端点ed 为 -1 

           如果 我们的左端点st <= 上一个存值的区间右端点 加 1 的话我们就只需要更新一下我们右节点 ed 就可以把两个区间合并了。为什么要加1?直接小于等于 ed 不行吗? 不可以 。因为ed那里已经有水了,只是 ed+1 的那个点没有水,所以如果我们的 l == ed+1的话也是可以算连接上了的。

          如果 我们的左端点st > 上一个存值的区间右端点 加 1 的话 就证明这两个区间必有间隙则更改我们的st 和 ed为新的区间端点。

         最终返回判断一下st是否为 1 并且 ed是否为管道长度。如果都符合就返回true,有一个不符合就是false;

            


     sort(p,p+cnt);
     int ed = -1 , st = -1;
     for(int i = 0 ; i < cnt ; i ++){
        if(p[i].x <= ed + 1 ) ed = max(ed , p[i].y);
        else st = p[i].x , ed = p[i].y;
     }
    return st == 1 and ed == m;

  

注意:区间合并就三种情况相交里包含两种,还有一种相离

代码:

#include <iostream>
#include <cstring>
#include <algorithm>
#define x first
#define y second

using namespace std;

const int N = 1e5+10;
typedef long long LL;
typedef pair<int, int> PII;
PII q[N], p[N];
LL n,m;

bool check(int mid){
     int cnt = 0 ; 
     for(int i = 0 ; i < n ; i ++){
         int L = q[i].x , S = q[i].y;
         if(mid >= S){
             int t = mid - S;
             int l = max(1,L-t) , r = min((LL)m,(LL)L+t);
                  p[cnt++]={l,r};
         }
     }
     sort(p,p+cnt);
     int ed = -1 , st = -1;
     for(int i = 0 ; i < cnt ; i ++){
        if(p[i].x <= ed + 1 ) ed = max(ed , p[i].y);
        else st = p[i].x , ed = p[i].y;
     }
    return st == 1 and ed == m;
}

int main()
{
    cin>>n>>m;
    for(int i = 0 ; i < n ; i ++){
        cin>>q[i].x>>q[i].y;
    }
    LL l = 0 , r = 2e9;
    while(l<r){
        LL mid = (l+r) / 2;
        if(check(mid)) r = mid;
        else l = mid + 1;
    }
    cout<<r;
    return 0;
}

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/469568.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

openEuler 22.03(华为欧拉)一键安装 Oracle 11G(231017)单机版

Oracle 一键安装脚本&#xff0c;演示 openEuler 22.03 一键安装 Oracle 11GR2 单机版过程&#xff08;全程无需人工干预&#xff09;&#xff1a;&#xff08;脚本包括 ORALCE PSU/OJVM 等补丁自动安装&#xff09; ⭐️ 脚本下载地址&#xff1a;Shell脚本安装Oracle数据库 …

高端嵌入式底层技术揭秘:《ARM汇编与逆向工程》

ARM架构简介 与传统的CISC&#xff08;Complex Instruction Set Computer&#xff0c;复杂指令集计算机&#xff09;架构相比&#xff0c;Arm架构的指令集更加简洁明了&#xff0c;指令执行效率更高&#xff0c;能够在更低的功耗下完成同样的计算任务&#xff0c;因此在低功耗…

2024流星全自动网页生成系统重构版源码

2024流星全自动网页生成系统重构版源码 源码介绍 流星全自动网页生成系统重构版源码分享&#xff0c;所有模板经过精心审核与修改&#xff0c;完美兼容小屏手机大屏手机&#xff0c;以及各种平板端、电脑端和360浏览器、谷歌浏览器、火狐浏览器等等各大浏览器显示。 为用户使…

FREERTOS信号量详解

信号量是操作系统中重要的一部分&#xff0c;信号量一般用来进行资源管理和任务同步&#xff0c;资源管理其实就是用变量来标记现有资源的数量&#xff0c;任务同步其实就是用标志位来控制任务的先后执行顺序&#xff0c;这些概念在操作系统中以及裸机开发中都有所涉及。 FreeR…

RK3588_Qt交叉编译环境搭建

buildroot编译 进入 /home/linux/plat/rk3588/sdk/buildroot 目录下&#xff0c;执行 Source ./envsetup.sh 选择具体平台编译&#xff0c;后再执行make编译 /home/linux/plat/rk3588/sdk/buildroot/output/OK3568/images 生成的rootfs.ext2镜像重新烧写到rk3568开发板中&…

React Native:跨平台移动应用开发的利器

&#x1f90d; 前端开发工程师、技术日更博主、已过CET6 &#x1f368; 阿珊和她的猫_CSDN博客专家、23年度博客之星前端领域TOP1 &#x1f560; 牛客高级专题作者、打造专栏《前端面试必备》 、《2024面试高频手撕题》 &#x1f35a; 蓝桥云课签约作者、上架课程《Vue.js 和 E…

外包2月,技术退步惊现!大专生逆袭大厂,全靠这份神秘资料!

大家好&#xff0c;我是一名大专生&#xff0c;19年通过校招进入湖南某软件公司&#xff0c;从事功能测试工作已近4年。今年8月&#xff0c;我意识到长期舒适的环境让我变得不思进取&#xff0c;技术停滞不前&#xff0c;甚至因此失去了谈了2年的女朋友。我下定决心&#xff0c…

下拉树级带搜索功能

可以直接复制粘贴到自己的项目里,方法处把接口替换一下 <template><div><el-popoverplacement"bottom"width"200"trigger"click"><el-inputslot"reference"class"mrInput":placeholder"placehol…

解决在命令行中输入py有效,输入python无效,输入python会跳转到microsoft store的问题| Bug

目录 如果你已经尝试过将python添加到系统变量在系统变量里把你自己的路径放到应用商店的路径之前删除windowsapps下的python.exe文件 如果你还未将python添加到系统变量没有python安装包且没有配置系统变量 如果你已经尝试过将python添加到系统变量 打开 运行&#xff0c;输入…

3.19网络编程

select实现的TCP并发服务器 #include <myhead.h> #define SER_IP "192.168.141.134" #define SER_PORT 8888 int main(int argc, const char *argv[]) {// 1、创建一个套接字int sfd -1;sfd socket(AF_INET, SOCK_STREAM, 0);if (sfd -1){perr…

香港科技大学广州|智能制造学域博士招生宣讲会—同济大学专场

时间&#xff1a;2024年3月28日&#xff08;星期四&#xff09;10:00 地点&#xff1a;同济大学嘉定校区济人楼310 报名链接&#xff1a;https://www.wjx.top/vm/mmukLPC.aspx# 宣讲嘉宾&#xff1a;崔华晨 助理教授 跨学科重点研究领域 •工业4.0 •智能传感器、自动光学检…

警惕!合规失守,某证券营业部遭监管警示

近日&#xff0c;青岛证监局网站发布的一则消息引起了市场的广泛关注。某证券股份有限公司青岛海口路证券营业部因使用未在中国证券业协会注册登记的劳务派遣人员办理业务&#xff0c;被青岛证监局采取出具警示函的监管措施。这一事件再次提醒各证券公司&#xff0c;合规经营的…

想入门Web测试,看这篇文章!

今天要谈的是很多软件测试工程师都需要面对的——Web测试 不管你是处在二十不惑的青春有你阶段还是三十而已的乘风破浪阶段我们都需要面对“Web测试”。 Web测试其实有以下几个方面&#xff1a; 1、页面测试 大多数的Web网站的网页都是html语言编写的&#xff0c;测试工程师…

【EDSR】《Enhanced Deep Residual Networks for Single Image Super-Resolution》

CVPR workshops-2017 code&#xff1a; https://github.com/limbee/NTIRE2017/tree/masterhttps://github.com/sanghyun-son/EDSR-PyTorch 文章目录 1 Background and Motivation2 Related Work3 Advantages / Contributions4 Method4.1 Residual blocks4.2 Single-scale mod…

Android自动化测试中短信的操作技巧!

一、发送短信的机制简介 短信作为一种重要的移动通信方式&#xff0c;在APP测试中也经常需要验证短信功能的正确性。为了避免大量手动操作设备发送短信的低效率&#xff0c;我们可以利用ADB命令达到自动发送短信的目的。 短信的发送需要手机短信APP的支持。命令行通过启动短信…

Data-Free Generalized Zero-Shot Learning 中文版

摘要 深度学习模型具有从大规模数据集中提取丰富知识的能力。然而&#xff0c;由于涉及到数据版权和隐私问题&#xff0c;数据共享变得越来越具有挑战性。因此&#xff0c;这妨碍了从现有数据向新的下游任务和概念有效转移知识。零样本学习&#xff08;ZSL&#xff09;方法旨在…

数据结构 --- 复杂度概念及计算讲解(时间复杂度,空间复杂度)

今天没有sao话&#xff0c;今天认真学习 一、时间复杂度 1、概念讲解 2、计算讲解 二、空间复杂度 1、概念讲解 2、计算讲解 三、常见复杂度对比 四、完结撒❀ 前言&#xff1a; 经常刷题的人都知道&#xff0c;我们在解决一道题时可能有多个解法&#xff0c;那么如何…

1、Java虚拟机学习-类的生命周期-加载阶段-以及怎样查看方法区中的对象和堆中对象的关联以及静态变量存在什么地方

类的生命周期 其中连接又可以分为3个小阶段 一、加载阶段 1、加载阶段第一步是类加载器根据类的全限定名通过不同的渠道以二进制流的方式获取字节码信息。 渠道: 2、类加载器在加载完类之后&#xff0c;Java虚拟机会将字节码中的信息保存在内存的方法区中。 方法区是虚拟…

HarmonyOS NEXT应用开发—投票动效实现案例

介绍 本示例介绍使用绘制组件中的Polygon组件配合使用显式动画以及borderRadius实现投票pk组件。 效果预览图 使用说明 加载完成后会有一个胶囊块被切割成两个等大的图形来作为投票的两个选项&#xff0c;中间由PK两字分隔开点击左边选项&#xff0c;两个图形会随着选择人数…

Http 超文本传输协议基本概念学习摘录

目录 HTTP协议 超文本传输协议 HyperText超文本 HTML超文本标记语言 HTTP协议原理 请求发送 服务器处理 响应发送 连接关闭或保持 HTTP协议版本 HTTP/0.9 HTTP/1.0 HTTP/1.1 HTTP/2 HTTP/3 HTTP请求方法 GET POST PUT DELETE HEAD OPTIONS HTTP请求头字…