首页 > 其他分享 >2024/3/11打卡管道(14届蓝桥杯省赛)——二分+区间合并

2024/3/11打卡管道(14届蓝桥杯省赛)——二分+区间合并

时间:2024-03-14 12:29:41浏览次数:30  
标签:11 int 阀门 long 蓝桥 static len 区间 打卡

目录

题目

思路

代码


题目

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

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

对于位于 L_i 的阀门,它流入的水在 T_i\ \ (T_i\geq S_i)时刻会使得从第 L_i-(T_i-S_i)段到第 L_i+(T_i-S_i) 段的传感器检测到水流。

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

输入格式

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

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

输出格式

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

数据范围

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

输入样例:

3 10
1 1
6 5
10 2

输出样例:

5

 

思路

        通过题意可以发现,假如说在 t 时刻满足题目要求,那么比 t 大的时刻,管道被覆盖的范围也一定大于等于 t 时刻的,一定满足要求,故具有单调性,此时可以想到用二分来做

如何确定一个时刻 t 所经过的长度是多少?我们通过 L_i  S_i  t 可以来确定一个阀门被打开后所流过的长度。L_i-(T_i-S_i) 即为左边能流到的最远的位置,L_i+(T_i-S_i)即为右边流到最远的位置。

获取到 t 时刻每一个被打开阀门的水流过的区间[\ L_i-(T_i-S_i),\ L_i+(T_i-S_i)\ ]后,如何合并所有的区间,判断是否将管道覆盖完全?此时可以想到区间合并的做法。将所有的区间合并起来,看是否覆盖完管道。

        区间合并:区间合并算法-CSDN博客

代码

注:此题的区间合并并不是两个区间有交集才能合并,例如[1, 2]和[3, 4]也可以进行合并成[1, 4]

注意以为r取到了2e9,再进行区间相加,可能或爆int

// 在 x 的时间内能否完成所有传感器检测到水流
// 在 x 时刻,每个能被打开的阀门被打开后,会有一段区间,那我们合并这段区间,判断是否能从0,覆盖到len

import java.io.*;
import java.util.*;

class Main{
    static int N = 100010;
    static int n,len;
    static int[] l = new int[N]; // 阀门位置
    static int[] s = new int[N]; // 阀门打开时间
    static Queue<PII> q = new PriorityQueue<>(); // 存储区间,按左端点排序
    public static void main(String[] args) throws IOException{
        BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
        String[] str = in.readLine().split(" ");
        n   = Integer.parseInt(str[0]);
        len = Integer.parseInt(str[1]);
        for(int i=1;i<=n;i++){
            str = in.readLine().split(" ");
            l[i] = Integer.parseInt(str[0]);
            s[i] = Integer.parseInt(str[1]);
        }
        
        // 进行二分,找最小时间
        long l = 0, r = 2000000000; // r需要取到2000000000,因为存在 1 1000000000
                                    //                               1000000000 1000000000 这种情况,那么时间就需要1999999999
        while(l<r){
            long mid = l+r>>1;
            if(check(mid)) r = mid; //当前mid时段可以满足
            else l = mid+1;
        }
        
        System.out.println(r);
    }
    public static boolean check(long u){
        // 获取所有的区间
        for(int i=1;i<=n;i++){
            long t = u-s[i];
            if(t>=0){ // u时间大于等于打开的时间
                long x = l[i]-t;
                long y = l[i]+t;
                q.add(new PII(x,y));
            }
        }
        
        // 对所有区间进行合并        
        long st = 0, ed = 0;
        while(!q.isEmpty()){
            PII i = q.poll();
            long x = i.l;
            long y = i.r;
            if(x<=ed+1){
                ed = Math.max(ed,y);
            }
            else return false;
        }
        if(ed<len) return false;
        else return true;
    }
}
class PII implements Comparable<PII>{ // 存储当前时间段被覆盖的区间
    long l;
    long r;
    public PII(long l,long r){
        this.l = l;
        this.r = r;
    }
    
    public int compareTo(PII i){
        return this.l-i.l>0?1:-1;
    }
}

标签:11,int,阀门,long,蓝桥,static,len,区间,打卡
From: https://blog.csdn.net/weixin_63001635/article/details/136631626

相关文章

  • Windows10, 11上,您可以使用以下PowerShell命令来启用Hyper-V功能组件 Windows server 2
    Windows11上,您可以使用以下PowerShell命令来启用Hyper-V功能组件:powershellCopyCodeEnable-WindowsOptionalFeature-Online-FeatureNameMicrosoft-Hyper-V-All这个命令将启用所有与Hyper-V相关的功能组件。请确保以管理员权限在PowerShell中运行此命令。执行以上命令后,系......
  • 2024-03-11-Nodejs(3-数据库与身份验证)
    3.数据库与身份验证3.1数据库基本概念数据库是用来组织、存储和管理数据的仓库;传统数据库中,数据结构分为数据库(database)、数据表(table)、数据行(tow)、字段(field)四大部分。3.2配置mysql模块安装mysql模块npminstallmysql建立连接constmysql=require('mysql')......
  • 2024-03-11-Nodejs(4-大事件项目)
    4.大事件项目4.1项目初始化项目整体架构图大事件项目 |--- db | |---index.js |---router | |---user.js |---router_handler | |---user.js |---schema | |---user.js |---app.js |---config.js4.1.1创建项目新建api_server文件夹作为项目......
  • 蓝桥杯Python国赛F题123(过70%代码)
    分析:明显考虑二分,(部分丑陋的笔记在下面,方便我自己看的,不喜勿喷)首先我们可以二分出包含在 [L,R]之间的完整的取值区间,[Get(a-1),Get(b)]因为左端点二分的是区间前端点,就是前端要包含在内,所以a-1然后就是对于两边突出部分进行计算,不知道为什么30%没有过,希望评论区......
  • 【BFS二叉树】113路径总和II
    113路径总和II给你二叉树的根节点root和一个整数目标和targetSum,找出所有从根节点到叶子节点路径总和等于给定目标和的路径。思路:题目最终输出的是路径,因此用BFS遍历的时候,需要记录走到每个节点的路径;又因为路径和是要等于某个目标值的,因此也需要记录目标和。⇒......
  • 蓝桥杯算法训练VIP-数组查找及替换
    题目1634:蓝桥杯算法训练VIP-数组查找及替换时间限制:3s内存限制:192MB提交:1629解决:890题目描述给定某整数数组和某一整数b。要求删除数组中可以被b整除的所有元素,同时将该数组各元素按从小到大排序。如果数组元素数值在A到Z的ASCII之间,替换为对应字母。输......
  • 备战蓝桥杯Day25 - 二叉搜索树查询和删除操作
    一、查询递归查询寻找的值比根节点大,遍历右子树;寻找的值比根节点小,遍历左子树。defqurey(self,node,val):ifnotnode:#没有节点,返回空returnNoneifnode.data<val:returnself.qurey(node.rchild,val)......
  • 2019蓝桥杯省赛B组
    2019蓝桥杯省赛B组A.组队方法一:人脑计算(每次选最大,但是一个人不能当两个位)最大值:98+99+98+97+98法二:枚举#include<iostream>using namespace std;//每个位置各编号的评分情况int one[20] = {97, 92, 0, 0, 89, 82, 0, 0, 0, 95, 0, 0, 94, 0, 0, 0......
  • [蓝桥杯 2019 省 A] 填空问题 E
    一、题目描述[蓝桥杯2019省A]填空问题ERSA解密二、问题简析本问题可以分成三部分求解:1、求\(p\)和\(q\):利用唯一分解定理,参考P1075[NOIP2012普及组]质因数分解2、求\(e\):利用拓展欧几里得定理,参考P1082[NOIP2012提高组]同余方程和拓展欧几里得算法3、......
  • P1138 第 k 小整数
    首先第一想到的是排序,想着刚好练练各种排序,然后看到每个数只计算一次,还全是正整数,于是直接读的时候记录读到啥数字,专门拿一个数组(代码中的b)记录,最后要第k个,直接数就可以,不成立的情况中间筛选了。#include<stdio.h>intmain(){intnum,k,a[10001]={0},b[10001]={0},tmp,......