【第十课】区间和并(acwing-803 / c++代码 / 思路 )

acwing-803区间和并 

【第十课】区间和并(acwing-803 / c++代码 / 思路 )_第1张图片

这道题直接说算法思路了。

思路

题目要求是,给定很多区间,要合并有交集的区间,并得出最终合并之后的区间个数。

思路就是我们把每一个区间存放在一个元素类型为pair的数组中(这里数组的元素就是区间),这样我们最终就可以直接输出数组的元素个数,也就是我们所求区间的个数

那么问题就在如何按要求合并区间呢?即本道题目的主要函数merge如何实现

我们创建一个临时数组res,用来存放符合要求的合并后的区间,这样res数组的元素个数就是我们的答案

首先要将数组中涉及到的区间进行左端点优先的排序。这样我们有了一个有序的对涉及到的区间进行判断的规则。 

我们从segments数组中进行扫描,对每一段区间都进行判断。进行区间端点的更新和合并。

最开始我们将区间start和end的初始值-2e9是一个非常小的数,这是为了确保第一个处理的区间能够被正确地处理。 

两个区间的关系无非三种情况:

【第十课】区间和并(acwing-803 / c++代码 / 思路 )_第2张图片

什么情况要合并?①和②,这两种情况只需要比较一下正在处理的区间右端点和①②这种右端点谁的更远右端点就更新为谁

当遇到③的时候,说明正在处理的区间已经处理完了,因为我们是按左端点排好序的,下一个将要比较的左端点已经比我正在处理的这个区间的右端点还远,那说明该区间处理完毕,其已经是我们的符合要求的区间了,放进res数组。③就是我们下一个要处理的区间。

最终将res数组赋值给segments数组。 

注意:merge函数的参数segments需要使用引用操作符&传入,这样最后对其赋值才会真正的改变main函数中的segments数组

代码如下

#include
#include
#include
using namespace std;
const int N=1e5+10;
int n,l,r;

typedef pair PII;
vector segments;//存储提到的线段

void merge(vector& segments)//注意引用操作符
{
    vector res;

    //将所有线段按左端点排序
    //pair类型的数据进行排序,优先以左端点排序 当first相同时才看second
    sort(segments.begin(),segments.end());

    //定义初始区间长度
    int start=-2e9,end=-2e9;

    //扫描涉及到的线段
    for(auto segment:segments)
    {
        if(end>n;
    while(n--)
    {
        cin>>l>>r;
        segments.push_back({l,r});
    }
    //区间和并
    merge(segments);
    //输出合并之后区间个数
    cout<

好啦,最后一个基础算法结束了,这个比较短。

如果有问题欢迎指出,非常感谢!!

也欢迎交流和建议哦! 

你可能感兴趣的:(算法基础,算法,c++)