区间合并
区间合并就是有两个区间我们把两个区间合并成一个区间
我们来看一道题
Acwing 803 区间合并
1.题目
给定 n nn 个区间 [ l i , r i ] [li,ri][li,ri],要求合并所有有交集的区间。
注意如果在端点处相交,也算有交集。
输出合并完成后的区间个数。
例如:[ 1 , 3 ] [1,3][1,3]和 [ 2 , 6 ] [2,6][2,6]可以合并为一个区间 [ 1 , 6 ] [1,6][1,6]。
输入格式
第一行包含整数 n nn。
接下来 n nn 行,每行包含两个整数 l ll 和 r rr。
输出格式
共一行,包含一个整数,表示合并区间完成后的区间个数。
数据范围
1 ≤ n ≤ 100000 , 1≤n≤100000,1≤n≤100000,
− 109 ≤ l i ≤ r i ≤ 109 −109≤li≤ri≤109−109≤li≤ri≤109
输入样例:
5
1 2
2 4
5 6
7 8
7 9
输出样例:
3
代码如下:
#include<iostream> // 引入输入输出流库
using namespace std; // 使用标准命名空间,避免每次使用std::前缀
#include<vector> // 引入向量容器库
#include<algorithm> // 引入算法库(如排序函数)
// 定义一个常量N,值为10010,可以用于定义数组大小等,但在本代码中未使用
const int N = 10010;
// 定义一个pair类型,表示区间的起始点和结束点,命名为PII(pair<int, int>)
typedef pair<int, int> PII;
// 定义合并区间的函数
// 函数接收一个由pair<int, int>(表示区间)组成的向量引用作为参数
void merge(vector<PII>& segs)
{
// 定义一个新的结果向量,用于存储合并后的区间
vector<PII> res;
// 对区间按照起始点进行排序,保证从左到右依次处理
sort(segs.begin(), segs.end());
// 初始化一个st(表示当前合并区间的起始点)和ed(表示当前合并区间的结束点)
// 初始值设置为很小的负数,表示还没有区间开始
int st = -2e9, ed = -2e9;
// 遍历所有的区间
for (auto seg : segs)
{
// 如果当前的区间无法与上一个区间合并(即前一区间的结束点小于当前区间的起点)
if (ed < seg.first)
{
// 如果st不是初始值,说明之前有一个区间,需要将其加入结果集
if (st != -2e9)
{
res.push_back({ st, ed }); // 将之前的合并区间存入结果
}
// 更新当前处理的区间为新的区间
st = seg.first, ed = seg.second;
}
else
{
// 如果当前区间可以和之前的区间合并,则更新结束点为二者较大的那个
ed = max(ed, seg.second);
}
}
// 循环结束后,最后一个区间还没有加入结果集,因此将其加入
if (st != -2e9)
res.push_back({ st, ed });
// 最后将合并后的结果赋值给输入的segs
segs = res;
}
int main()
{
// 读取区间个数
int n;
cin >> n;
// 创建一个向量,用于存储所有输入的区间
vector<PII> segs;
// 通过循环读取n个区间的起点和终点
while (n--)
{
int l, r;
cin >> l >> r; // 读取区间的左端点l和右端点r
segs.push_back({ l, r }); // 将区间存入segs向量
}
// 调用merge函数,将segs中的区间进行合并
merge(segs);
// 输出合并后区间的数量
cout << segs.size() << endl;
return 0; // 程序结束,返回0表示程序正常退出
}
区间合并源码