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;
}
相关推荐
碧海银沙音频科技研究院2 小时前
杰理项目开发大全课程
人工智能·深度学习·算法
宏笋2 小时前
C++11完美转发的作用和用法
c++
格发许可优化管理系统2 小时前
MathCAD许可类型全面解析:选择最适合您的许可证
c++
风一样的航哥2 小时前
LeetCode 2615 等值距离和:前缀和优化O(n)解法深度解析
数据结构·算法·leetcode
生成论实验室2 小时前
生成态势猜想:一种统一的宇宙动力学语法
人工智能·科技·神经网络·算法·信息与通信
旖-旎3 小时前
深搜(二叉树的所有路径)(6)
c++·算法·leetcode·深度优先·递归
啦啦啦_99993 小时前
3. KNN算法之 常用的距离度量方式(欧式&曼哈顿&切比雪夫&闵式距离)
算法
GIS阵地3 小时前
QGIS的分类渲染核心类解析
c++·qgis·开源gis
朝风工作室3 小时前
实时全景拼接|支持任意路数输入,8*8K RTX3050 实测 10ms 内
图像处理·算法·计算机视觉