AcWing 905. 区间选点

题目描述

给定 N 个闭区间 [ai,bi],请你在数轴上选择尽量少的点,使得每个区间内至少包含一个选出的点。

输出选择的点的最小数量。

位于区间端点上的点也算作区间内。

输入格式

第一行包含整数 N,表示区间数。

接下来 N 行,每行包含两个整数 ai,bi,表示一个区间的两个端点。

输出格式

输出一个整数,表示所需的点的最小数量。

数据范围

\(1≤N≤10^5\)
\(−10^9≤ai≤bi≤10^9\)

输入样例:

3
-1 1
2 4
3 5

输出样例:

2

贪心算法求解

分析

把所有区间按照右端点排序

初始化当前区间ed = -1e9 - 7,遍历所有区间u

  1. 如果区间u的左端点 > ed,说明本区间与区间u没有交集,res++,并且更新 ed = u的右端点
  2. 否则说明本区间与区间u没有交集,只要在ed取一个点,这个点一定既属于本区间,又属于区间u,直接pass区间u即可

具体证明:https://www.acwing.com/solution/content/16905/

代码

#include<iostream>
#include<algorithm>
#include<vector>
using namespace std;
typedef pair<int, int> Pair;

const int N = 100010;
vector<Pair> s;

bool cmp(Pair a, Pair b)
{
    return a.second < b.second;
}

int main()
{
    int n;
    int res = 0;
    scanf("%d", &n);
    for(int i = 0; i < n; i++)
    {
        Pair t;
        scanf("%d%d", &t.first, &t.second);
        s.push_back(t);
    }
    sort(s.begin(), s.end(), cmp); // 按照区间右端点从小到大排序
    int ed = -1e9 - 7; 
    for(Pair t : s)
    {
        if(ed < t.first)
        {
            res ++;
            ed = t.second;
        }
    }
    cout << res << endl;
    return 0;
}

时间复杂度

O(n)

参考文章

https://www.acwing.com/solution/content/16905/

posted @ 2022-02-27 11:57  VanHope  阅读(49)  评论(0编辑  收藏  举报