csp信奥赛C++高频考点专项训练之贪心算法 --【区间贪心】:区间覆盖(加强版)

csp信奥赛C++高频考点专项训练之贪心算法 --【区间贪心】:区间覆盖(加强版)

题目描述

已知有 N N N 个区间,每个区间的范围是 [ s i , t i ] [s_i,t_i] [si,ti],请求出区间覆盖后的总长。

输入格式

第一行一个正整数 N N N,表示区间个数。

接下来 N N N 行,每行两个正整数,表示 s i s_i si 和 t i t_i ti。

输出格式

共一行,一个正整数,为覆盖后的区间总长。

输入输出样例 1
输入 1
复制代码
3
1 100000
200001 1000000
100000000 100000001
输出 1
复制代码
900002
说明/提示

对于 40 % 40 \% 40% 的数据, N ≤ 1000 N \le 1000 N≤1000, 1 ≤ s i < t i ≤ 10000 1 \le s_i < t_i \le 10000 1≤si<ti≤10000。

对于 100 % 100 \% 100% 的数据 , N ≤ 10 5 N \le 10^5 N≤105, 1 ≤ s i < t i ≤ 10 17 1 \le s_i < t_i \le 10^{17} 1≤si<ti≤1017。

思路分析

给定 N 个闭区间 [ s i , t i ] [s_i, t_i] [si,ti],需要求它们合并后的总长度。由于坐标最大可达 10 17 10^{17} 1017,不能使用数组差分,必须通过排序 + 贪心合并。

  1. 排序:将所有区间按左端点升序排列。这样能保证从左到右依次处理,当前区间只可能和后续区间重叠或相邻。
  2. 合并
    • 初始化当前合并段的左右端点为第一个区间的 lr
    • 遍历后续区间:
      • 若当前区间的左端点 a[i].l 大于 当前合并段的右端点 cur,说明两段之间有空隙,无法合并。此时将当前段的长度 cur - cul + 1 累加到答案,并开始一个新的合并段(用当前区间重置 culcur)。
      • 否则(a[i].l <= cur),说明有重叠或相邻(闭区间下 [1,2][3,4] 不相邻,因为 3 > 2,所以用 > 判断不会错误合并不相邻区间),此时更新当前段的右端点 cur = max(cur, a[i].r)
    • 循环结束后,将最后一段的长度加入答案。
  3. 输出:输出累加的总长度。

时间复杂度 O ( N log ⁡ N ) O(N \log N) O(NlogN),空间复杂度 O(N)。


代码实现

cpp 复制代码
#include<bits/stdc++.h>
using namespace std;
typedef long long ll; // 使用ll表示long long,适应1e17的大数
const int N=1e5+10; // 最大区间数+10
int n; // 区间个数
struct node{ // 区间结构体
    ll l,r; // 左端点、右端点
}a[N]; // 存储所有区间
bool cmp(node a,node b){// 按左端点升序排序的比较函数
    return a.l<b.l;
}
int main(){
    cin>>n;
    for(int i=1;i<=n;i++){
        cin>>a[i].l>>a[i].r;
    }
    sort(a+1,a+n+1,cmp);// 将区间按左端点排序
    ll cul=a[1].l;// 当前合并段的左端点(current left)
    ll cur=a[1].r;// 当前合并段的右端点(current right)
    ll ans=0; // 总覆盖长度
    for(int i=2;i<=n;i++){// 从第二个区间开始合并
        if(a[i].l>cur){// 当前区间与之前段不相连(有间隙)
            ans+=(cur-cul+1);// 加上之前段的长度
            cul=a[i].l; // 开启新段:左端点为当前区间左端点
            cur=a[i].r; // 右端点为当前区间右端点
        }else{ // 可以合并
            cur=max(cur,a[i].r);// 扩展当前段的右端点
        }
    }
    ans+=(cur-cul+1); // 加上最后一段的长度
    cout<<ans; // 输出结果
    return 0;
}

功能分析

  • 输入处理:读取整数 N 和 N 行区间,每个区间包含左右端点。
  • 排序 :调用 sort 并传入自定义比较函数 cmp,将所有区间按照左端点从小到大排列。
  • 贪心合并
    • 维护当前合并段的左右端点 culcur,初始化为第一个区间。
    • 依次考察每个后续区间:
      • 如果当前区间的左端点 大于 cur,说明中间有缝隙,不能合并:将当前段的长度加入答案,并重置新段为当前区间。
      • 否则,说明当前区间与当前段有重叠或恰好相接。
    • 循环结束后,将最后一段的长度累加。
  • 输出:打印最终总长度。

正确性:基于排序后贪心合并,每次遇到不重叠区间就结算当前段,保证每个点只被计数一次,最终得到所有区间覆盖的并集总长度。

边界处理

  • N=1 时,循环不会执行,直接输出 cur-cul+1,正确。
  • 当区间有包含关系时,cur = max(cur, a[i].r) 能正确扩展右端点。
  • 数据范围使用 long long,避免溢出。

各种学习资料,助力大家一站式学习和提升!!!

cpp 复制代码
#include<bits/stdc++.h>
using namespace std;
int main(){
	cout<<"##########  一站式掌握信奥赛知识!  ##########";
	cout<<"#############  冲刺信奥赛拿奖!  #############";
	cout<<"######  课程购买后永久学习,不受限制!   ######";
	return 0;
}

【秘籍汇总】(完整csp信奥赛C++学习资料):

1、csp/信奥赛C++,完整信奥赛系列课程(永久学习):

https://edu.csdn.net/lecturer/7901 点击跳转

2、CSP信奥赛C++竞赛拿奖视频课:

https://edu.csdn.net/course/detail/40437 点击跳转

https://edu.csdn.net/course/detail/41081 点击跳转

3、csp信奥赛高频考点知识详解及案例实践:

CSP信奥赛C++动态规划:
https://blog.csdn.net/weixin_66461496/category_13096895.html点击跳转

CSP信奥赛C++标准模板库STL:
https://blog.csdn.net/weixin_66461496/category_13108077.html 点击跳转

信奥赛C++提高组csp-s知识详解及案例实践:
https://blog.csdn.net/weixin_66461496/category_13113932.html 点击跳转

4、csp信奥赛冲刺一等奖有效刷题题解:

CSP信奥赛C++初赛及复赛高频考点真题解析(持续更新): https://blog.csdn.net/weixin_66461496/category_12808781.html 点击跳转

信奥赛C++提高组csp-s初赛&复赛真题题解(持续更新):
https://blog.csdn.net/weixin_66461496/category_13125089.html 点击跳转

5、GESP C++考级真题题解:

GESP(C++ 一级+二级+三级)真题题解(持续更新):https://blog.csdn.net/weixin_66461496/category_12858102.html 点击跳转

GESP(C++ 四级+五级+六级)真题题解(持续更新):https://blog.csdn.net/weixin_66461496/category_12869848.html 点击跳转

GESP(C++ 七级+八级)真题题解(持续更新):
https://blog.csdn.net/weixin_66461496/category_13117178.html 点击跳转

· 文末祝福 ·

cpp 复制代码
#include<bits/stdc++.h>
using namespace std;
int main(){
	cout<<"跟着王老师一起学习信奥赛C++";
	cout<<"    成就更好的自己!       ";
	cout<<"  csp信奥赛一等奖属于你!   ";
	return 0;
}
相关推荐
Aaron15882 小时前
全频段 SDR干扰源模块解决方案(星链干扰、LORA无人机干扰)
人工智能·算法·fpga开发·硬件架构·硬件工程·无人机·信息与通信
AI科技星2 小时前
全域数学·球面拓扑微扰标准系数η=0.01 应用详解(典籍正式版)
人工智能·算法·数学建模·数据挖掘·机器人
Peter·Pan爱编程2 小时前
成员函数与 this 指针:函数属于数据
c++
逻辑君2 小时前
物理学研究报告【20260001】
人工智能·算法
AI科技星2 小时前
算法联盟·全域数学公理体系下黑洞标量毛发与LVK引力波O4全维理论、求导、证明、计算、验证、分析
人工智能·线性代数·算法·架构·学习方法·量子计算
谙弆悕博士2 小时前
【附C语言源码】C语言 栈结构 实现及其扩展操作
c语言·开发语言·数据结构·算法·链表·指针·
YuanDaima20482 小时前
图论基础原理与题目说明
数据结构·人工智能·python·算法·图论·手撕代码
AI人工智能+电脑小能手2 小时前
【大白话说Java面试题 第53题】【JVM篇】第13题:JVM采用什么算法判断一个对象是否需要被回收?
java·jvm·算法·面试
小赵不会秃头2 小时前
数据结构Day 06:线性结构、库操作及 Makefile 完整学习笔记
java·linux·数据结构·算法·面试
music score2 小时前
google 的C++自动化测试框架详解(Google Test)(2)
c++·qt·lucene