区间合并

区间合并

区间合并,顾名思义,就是将一系列能合并的区间合并

核心代码

void merge(vector<PII>&segs)
{
    int st = 2e9, ed = -2e9;
    vector<PII> res;
    sort(segs.begin(), segs.end());
    //注意,(st, ed)的更新顺序相比于(i.first, i.second)是落后的
    for (auto i : segs)
    {
        if (ed < i.first)
        {
            if (st != 2e9) res.push_back({st, ed});
            st = i.first, ed = i.second;
        }
        else ed = max (ed, i.second);
    }
    if (st != 2e9) //这里是为了防止出现参数为空的情况
    res.push_back({st, ed});
    segs = res;
}

例题- 救生员

题目链接:https://www.acwing.com/problem/content/1752/
代码

#include<iostream>
#include<algorithm>
#include<vector>
using namespace std;

typedef pair<int, int>PII;
vector<PII> segs;

int n;

int merge(vector<PII>& segs)//引用, 一方面是为了提高速度,还能增加程序的耦合度
{
	int res = 0;
	sort(segs.begin(), segs.end());
/*
核心思想:从头到尾,分别枚举缺少i号点的情况,最后取最大值
*/
	for (int i = 0; i < n; i ++ )
	{
        //注意下面两行要放到外层循环里面,因为我们相当于将“res.push_back({st, ed})"操作换成了,计算缺少i组点的情况下,对应的sum值。
		int sum = 0;
		int st = 2e9, ed = -2e9;
		for (int j = 0; j < n; j ++ )
		{
			if (i == j) continue;
			if (ed < segs[j].first)
			{
				if (st != 2e9) sum += ed - st;
				st = segs[j].first, ed = segs[j].second;
			}
			else ed = max(ed, segs[j].second);
		}
		if (st != 2e9) sum += ed - st;
		res = max(res, sum);
	}
	return res;
}

int main()
{
	cin >> n;
	for (int i = 0;  i < n; i ++ )
	{
		int l, r;
		cin >> l >> r;
		segs.push_back({l, r});
	}
	cout << merge(segs) << endl;
	return 0;
}

本题虽然简单,但是却体现了区间合并的本质及实现方式,是基于模板题的一种变式。
posted on 2023-01-10 19:55  Huayushanchuan  阅读(26)  评论(0编辑  收藏  举报