算法刷题day29:区间合并

目录

  • 引言
  • 概念
  • 一、挤牛奶
  • 二、区间合并
  • 三、校门外的树
  • 四、管道

引言

区间合并这种题,是比较小的题,一般是不会直接出成一道题来考你的,一般思路都是给一道题,里面包含了各种的点,每一个点都需要一个想区间合并这样的知识点来破解,所以会是很重要的,并且要能抽象出各种模型的能力也是非常重要的,加油!


概念

区间合并:其实就是个模板,可以参考我之前写过的博客 区间合并


一、挤牛奶

标签:区间合并

思路:就是按区间合并的模板,当前遍历的区间已经不能合并了,那么就可以计算出上一个区间的长度了,也可以求出来中间空出了多长的区间,统计一下各自的最大值即可。最后一个区间不论是什么情况,它的长度都不会被算进来,所以需要最后单独比较一下最后一个区间的长度。

题目描述:

每天早上 5 点,三名农夫去牛场给奶牛们挤奶。

现在从 5 点开始按秒计时,第一名农夫在第 300 秒开始给牛挤奶,并在第 1000 秒停止挤奶。

第二名农夫在第 700 秒开始给牛挤奶,并在第 1200 秒停止挤奶。

第三名农夫在第 1500 秒开始给牛挤奶,并在第 2100 秒停止挤奶。

从开始挤奶到挤奶完全结束,这一期间,至少存在一名农夫正在挤奶的连续时间段的长度最长为 900 秒(第 300 秒至第 1200 秒),完全没有任何农夫在挤奶的连续时间段的长度最长为 300 秒(第 1200 秒至第 1500 秒)。

现在给你 N 名农夫挤 N 头奶牛的工作时间表,请你求出:

至少存在一名农夫正在挤奶的连续时间段的最长长度。
没有任何农夫在挤奶的连续时间段的最长长度。
注意:本题中给出的所有时间均为时刻(时间点),因此在本题中挤奶区间 [100,200] 和 [201,300] 中间会有长度为 1  秒的间歇时间。

输入格式
第一行包含整数 N,表示农夫数量。

接下来 N 行,每行包含两个非负整数 l,r,表示农夫挤奶的开始时刻和结束时刻。

输出格式
共一行,包含两个整数,分别表示最长连续挤奶时间以及最长连续无人挤奶时间。

数据范围
1≤N≤5000,0≤l≤r≤106
输入样例:
3
300 1000
700 1200
1500 2100
输出样例:
900 300

示例代码:

#include <bits/stdc++.h>

using namespace std;

typedef long long LL;
typedef pair<int,int> PII;
#define x first
#define y second

const int N = 5010;

int n;
PII segs[N];

int main()
{
    ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
    
    cin >> n;
    for(int i = 0; i < n; ++i) cin >> segs[i].x >> segs[i].y;
    
    sort(segs, segs+n);
    
    int res1 = 0, res2 = 0;
    int l = segs[0].x, r = segs[0].y;
    for(int i = 1; i < n; ++i)
    {
        if(segs[i].x > r)
        {
            res1 = max(res1, r - l);
            res2 = max(res2, segs[i].x - r);
            l = segs[i].x, r = segs[i].y;
        }
        else
        {
            r = max(r, segs[i].y);
        }
    }
    
    res1 = max(res1, r - l);
    cout << res1 << " " << res2 << endl;
    
    return 0;
}

二、区间合并

标签:区间合并、模板题

思路:模板题没什么说的。

题目描述:

给定 n 个区间 [li,ri],要求合并所有有交集的区间。

注意如果在端点处相交,也算有交集。

输出合并完成后的区间个数。

例如:[1,3] 和 [2,6] 可以合并为一个区间 [1,6]。

输入格式
第一行包含整数 n。

接下来 n 行,每行包含两个整数 l 和 r。

输出格式
共一行,包含一个整数,表示合并区间完成后的区间个数。

数据范围
1≤n≤100000,−109≤li≤ri≤109
输入样例:
5
1 2
2 4
5 6
7 8
7 9
输出样例:
3

示例代码:

#include <bits/stdc++.h>

using namespace std;

typedef long long LL;
typedef pair<int,int> PII;
#define x first
#define y second

const int N = 1e5+10;

int n;
PII segs[N];

int main()
{
    ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
    
    cin >> n;
    for(int i = 0; i < n; ++i) cin >> segs[i].x >> segs[i].y;
    sort(segs, segs+n);
    
    int res = 0;
    int l = -2e9, r = -2e9;
    for(int i = 0; i < n; ++i)
    {
        if(segs[i].x > r)
        {
            res++;
            l = segs[i].x, r = segs[i].y;
        }
        else
        {
            r = max(r, segs[i].y);
        }
    }
    
    cout << res << endl;
    
    return 0;
}

三、校门外的树

标签:区间合并、差分

思路1:看到在一个区域内操作,并且结果看的是有没有操作过,我就知道可以用差分了。差分就是使用 O ( 1 ) O(1) O(1) 的时间复杂度在 [ l , r ] [l,r] [l,r] 的范围内加上一个数,值得注意的是,区间是从 [0,n] 的,差分的下标需要从 1 1 1 开始,所以我们只要把所有的位置向后偏移一位即可,剩下的就是常规操作了,最后看从 [ 1 , n + 1 ] [1,n+1] [1,n+1] 中有几个没有被操作过,累加即可。差分可以看我以前的博客 前缀和与差分

思路2:这道题跟挤牛奶那道题很像,只不过挤牛奶那道题给出的数据左边界已经给了,而这道题给出的数据有可能还不挨左边界,并且该题的合并的条件不同,条件是树,只要树移了就算连着,比如 [ 1 , 2 ] , [ 3 , 4 ] [1,2],[3,4] [1,2],[3,4] 能合并成 [ 1 , 4 ] [1,4] [1,4] ,所以条件得改一下,并且初始的 l , r l,r l,r 也要好好考虑一下初始值,使得不用特判。详情见代码。

题目描述:

某校大门外长度为 L 的马路上有一排树,每两棵相邻的树之间的间隔都是 1 米。

我们可以把马路看成一个数轴,马路的一端在数轴 0 的位置,另一端在 L 的位置;数轴上的每个整数点,即 0,1,2,……,L,都种有一棵树。

由于马路上有一些区域要用来建地铁。

这些区域用它们在数轴上的起始点和终止点表示。

已知任一区域的起始点和终止点的坐标都是整数,区域之间可能有重合的部分。

现在要把这些区域中的树(包括区域端点处的两棵树)移走。

你的任务是计算将这些树都移走后,马路上还有多少棵树。

输入格式
输入文件的第一行有两个整数 L 和 M,L 代表马路的长度,M 代表区域的数目,L 和 M 之间用一个空格隔开。

接下来的 M 行每行包含两个不同的整数,用一个空格隔开,表示一个区域的起始点和终止点的坐标。

输出格式
输出文件包括一行,这一行只包含一个整数,表示马路上剩余的树的数目。

数据范围
1≤L≤10000,1≤M≤100
输入样例:
500 3
150 300
100 200
470 471
输出样例:
298

示例代码1: 差分

#include <bits/stdc++.h>

using namespace std;

typedef long long LL;
typedef pair<int,int> PII;
#define x first
#define y second

const int N = 10010;

int n, m;
int b[N];

int main()
{
    ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
    
    cin >> n >> m;
    while(m--)
    {
        int l, r;
        cin >> l >> r;
        l++, r++;
        b[l]++, b[r+1]--;
    }
    
    for(int i = 1; i <= n + 1; ++i)
    {
        b[i] += b[i-1];   
    }
    
    int res = 0;
    for(int i = 1; i <= n + 1; ++i)
    {
        if(!b[i]) res++;   
    }
    
    cout << res << endl;
    
    return 0;
}

示例代码2: 区间合并

#include <bits/stdc++.h>

using namespace std;

typedef long long LL;
typedef pair<int,int> PII;
#define x first
#define y second

const int N = 110;

int n, m;
PII segs[N];

int main()
{
    ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
    
    cin >> n >> m;
    for(int i = 0; i < m; ++i) cin >> segs[i].x >> segs[i].y;
    sort(segs, segs+m);
    
    int res = 0;
    int l = -1, r = -1;
    for(int i = 0; i < m; ++i)
    {
        if(segs[i].x > r + 1)
        {
            res += segs[i].x - r - 1;
            l = segs[i].x, r = segs[i].y;
        }
        else
        {
            r = max(r, segs[i].y);
        }
    }
    
    res += n - r;
    cout << res << endl;
    
    return 0;
}

四、管道

标签:二分、区间合并

思路:一般求最值都是可以用二分出来的,假如最短时间为 m i d mid mid ,那么大于等于 m i d mid mid 的都是满足条件的,而小于 m i d mid mid 的都是不满足条件的,也就是该题具有二段性,性质如下图所示。所以我们可以用二分来枚举找到边界。对于 c h e c k check check 函数,可以将在 m i d mid mid 时间当前阀门流过的水的范围看作一个区间,如果所有的区间合并为整个管道,那么就满足。值得注意的是,这道题也是不需要边界挨着,只要是区间相邻就可以合并(由题意可知)。
在这里插入图片描述

题目描述:

有一根长度为 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≤105;
对于所有评测用例,1≤n≤105,1≤Si,len≤109,1≤Li≤len,Li−1<Li。

输入样例:
3 10
1 1
6 5
10 2
输出样例:
5

示例代码:

#include <bits/stdc++.h>

using namespace std;

typedef long long LL;
typedef pair<int,int> PII;
#define x first
#define y second

const int N = 1e5+10;

int n, m;
int L[N], S[N];
PII segs[N];

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

int main()
{
    ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
    
    cin >> n >> m;
    for(int i = 0; i < n; ++i) cin >> L[i] >> S[i];
    
    int l = 1, r = 2e9;
    while(l < r)
    {
        int mid = (LL)l + r >> 1;
        if(check(mid)) r = mid;
        else l = mid + 1;
    }
    
    cout << r << endl;
    
    return 0;
}

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

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

相关文章

【代表作神刊】经管社科类,稀缺SSCI2区期刊,仅14天见刊,2天检索!!

2024年3月第二周&#xff0c;我处EA-ISET协会推荐发表的文章目前都在有序进行中&#xff0c; 新增检索5篇&#xff0c;SSCI5篇&#xff1b; 新增见刊10篇&#xff0c;SSCI1篇&#xff0c;CNKI5篇&#xff0c;谷歌普刊4篇&#xff1b; 现整理部分录用案例&#xff0c;时间节点…

新书速览|机器学习实战:视频教学版

掌握线性回归、分类、数据降维、聚类、关联规则、协同过滤算法及应用 本书内容 《机器学习实战&#xff1a;视频教学版》基于Python语言详细讲解机器学习算法及其应用&#xff0c;用于读者快速入门机器学习。本书配套示例源代码、PPT课件、教学视频、教学大纲、习题与答案、作者…

Voip测试工具

SIPp是一个测试SIP协议性能的工具软件。这是一个GPL的开放源码软件。 sipp是安装在linux机器上的 SIPp可以用来测试许多真实的SIP设备&#xff0c;如SIP代理&#xff0c;B2BUAs,SIP媒体服务器&#xff0c;SIP/x网关&#xff0c;SIP PBX&#xff0c;等等&#xff0c;它也可以模…

for、while、do...while循环的使用

本篇文章只记录for、while、do...while循环的使用&#xff0c;由于java循环较为简单&#xff0c;所以直接上代码。 1、for循环 需求&#xff1a;循环遍历求和 1-100。 public class Demo {public static void main(String[] args) {int sum 0;for (int i 1; i < 100; i…

技术驱动校园招聘:Java+SpringBoot+Vue的实践之旅

✍✍计算机编程指导师 ⭐⭐个人介绍&#xff1a;自己非常喜欢研究技术问题&#xff01;专业做Java、Python、微信小程序、安卓、大数据、爬虫、Golang、大屏等实战项目。 ⛽⛽实战项目&#xff1a;有源码或者技术上的问题欢迎在评论区一起讨论交流&#xff01; ⚡⚡ Java实战 |…

Linux——线程(2)

在上一篇博客中我介绍了Linux中的线程是什么样的&#xff0c;就如同进程可以通过 fork创建&#xff0c;可以被终止&#xff0c;可以退出一样&#xff0c;线程也可以被我们用户控制&#xff0c;这 篇博客我会介绍线程的控制&#xff0c;并且基于线程的控制所产生的一些问题进行 …

麒麟信安集控云工作站解决方案,驱动电网奔向数字化转型新未来!

集控站是电网运行信息的集中监控中心&#xff0c;实现对电网设备状态感知、缺陷发现、主动预警、风险管控和应急处置的全流程闭环管控&#xff0c;在保障日常供电方面发挥重要作用。此前集控站主要采用网络KVM矩阵&#xff0c;其数字化转型面临延长距离受限、无法实现跨辖区延伸…

Redis及其常用命令(二)

SortedSet类型 在此类型中&#xff0c;每个元素都有一个分数 key -> string value -> sorted([socre,member],[score,member]...) # 添加元素 zadd key score member # 遍历集合 zrange key start stop [withscores] #升序 zrevrange key start stop [withscores]#降序…

二、vue-cli项目搭建

系列文章&#xff1a; vue实战&#xff08;商城后台管理系统&#xff09;&#xff1a;http://t.csdnimg.cn/f6Fqa vue.js :http://t.csdnimg.cn/mljxv 目录 系列文章&#xff1a; vue实战&#xff08;商城后台管理系统&#xff09;&#xff1a;http://t.csdnimg.cn/f6Fqa vue…

O2OA(翱途)流程引擎中如何修改,定制流程的流转记录

使用场景 在特殊使用场景中需要定制流转记录,比如业务上需要修改用户名称,修改时间和意见等. 比如一下场景: 需要将用户"b(company01)"的流转记录修改为"d(company01)". 手工修改 系统默认提供维护工具,在有权限的情况下可以直接进行维护. 通过"左…

AI壁纸号一周增加上千粉丝,轻松变现的成功案例分享

前言 随着AI绘画技术的发展&#xff0c;传统的互联网副业壁纸号在新的技术加持下迎来了第二春。本文将分享一位壁纸号创作者的成功案例&#xff0c;并为大家提供创作门槛和硬件要求等相关信息。 该项目的创作门槛极低&#xff0c;基本上可以由AI完成内容创作。不过&#xff0…

“我快无聊死了”用英语怎么说?柯桥英语口语学习,成人零基础学外语

每日一句 Im bored to death. 我快无聊死了。 单词解析&#xff1a; bored / bɔːd / adj.无聊的&#xff0c;厌倦的 bored to d15857575376eath&#xff1a;指非常无聊或厌烦&#xff0c;达到了极点的程度。 "bored" 和 "boring" 都与无聊相关&#…

Python编程从入门到实践中的一些误区

1.num 使用num时python报错&#xff0c;后来查过后才知道是因为python不支持自增或自减&#xff0c;可以用1。 2.字符串和非字符串连接 要先将非字符串转换为字符串类型之后才能连接 print&#xff08;2int&#xff08;‘2’&#xff09;&#xff09;#4 3.关键字参数必须在未…

基于springboot+vue的电子商务系统(源码+论文)

目录 前言 一、功能设计 二、功能实现 三、库表设计 四、论文 前言 各种购物网站现在已经成了生活中不可缺少的调味品,比如比较全面的淘宝网,还有可以进行交流问答的小红书APP,还有电脑爱好者者们的天堂京东商城等等。拥有一个功能丰富、操作方便的电子商务销售网站,可以汇…

jenkins部署go应用 基于docker-compose

丢弃旧的的构建 github 拉取代码 指定go的编译版本 编写docker-compose 文件 docker-compose.yaml version: "3"services:game-api:image: centos:7working_dir: /appcontainer_name: game-api #自定义command: "./game-api -f conf/config.yaml"por…

针对二进制储存方式深度解析

int main() { int a[4] { 1, 2, 3, 4 }; int* p1 (int*)(&a 1); int* p2 (int*)((int)a 1); printf("%x %x", p1[-1], *p2); return 0; } X86环境下运行 %x打印16进制。 整形指针1跳过四个字节&#xff0c;((int)a 1)强制类型转换为…

【记录 | 基础动态规划】:数字三角形

数字三角形 链接:[USACO1.5] [IOI1994]数字三角形 Number Triangles 题目描述 观察下面的数字金字塔。 写一个程序来查找从最高点到底部任意处结束的路径,使路径经过数字的和最大。每一步可以走到左下方的点也可以到达右下方的点。 在上面的样例中,从 7 → 3 → 8 → 7 →…

python8综合案例

目标&#xff1a; 1 2 代码 文件的内容读取就完成了 数据的封装 就获得了一个日期的总销售额字典、 pingan 健康

3个小技巧,创建高级简历设计

看厌了简历推荐模板平台千篇一律&#xff0c;您有没有考虑过&#xff0c;自己完成一个独特的简历模板制作&#xff1f;为满足大家量身定做的简历需求&#xff0c;与大家分享一个在即时设计中制作简历模板的三个小技巧。 1、复制/粘贴 进入在线设计新时代过后&#xff0c;许多…

AI情报专刊来啦!《“AI换脸”威胁研究与安全策略》

目录 “AI换脸”常见的诈骗套路 1、伪造账号造谣传谣 2、冒充熟人进行诈骗 3、伪造身份申请银行贷款 4、“网络钓鱼”更加难以识别 5、冒充他人远程面试入职 6、冒名登录盗走银行余额 “AI换脸”的产业链 “AI换脸”使用到的技术 人脸识别和关键点检测 图像/视频合成技术 生成对…