AcWing 905.区间选点
题目链接:AcWing 905.区间选点
给定 N N N 个闭区间 [ a i , b i ] [a_i,b_i] [ai,bi],请你在数轴上选择尽量少的点,使得每个区间内至少包含一个选出的点。
输出选择的点的最小数量。
位于区间端点上的点也算作区间内。
输入格式
第一行包含整数 N N N,表示区间数。
接下来 N N N 行,每行包含两个整数 a i , b i a_i,b_i ai,bi,表示一个区间的两个端点。
输出格式
输出一个整数,表示所需的点的最小数量。
数据范围
1
≤
N
≤
1
0
5
1\leq N \leq10^5
1≤N≤105,
−
1
0
9
≤
a
i
≤
b
i
≤
1
0
9
-10^9\leq a_i \leq b_i \leq 10^9
−109≤ai≤bi≤109
输入样例:
3
-1 1
2 4
3 5
输出样例:
2
解题思路:
y总真言:对于贪心问题,若没有思路,先排序。
- 将每个区间按右端点从小到大排序。
- 枚举每个区间,若左端点大于大于当前选点的位置,则 选点个数+1,并将选点个数设置位当前区间右端点(尽可能使得后面的区间都能包含它);否则 pass这个区间(因为它包含当前选的点),
初始情况可以视为当前选点位置在负无穷大,任何一个区间也不不包含它。
解法1:sort
函数传入 cmp
排序规则
#include <iostream>
#include <algorithm>
using namespace std;
const int N = 100010;
struct range
{
int l, r;
}R[N];
bool cmp(range r1, range r2)
{
return r1.r < r2.r;
}
int main()
{
int n;
cin >> n;
for (int i = 1; i <= n; i++)
{
cin >> R[i].l >> R[i].r;
}
sort(R + 1, R + n + 1, cmp);
// 若数组下标以 1 开始,则要这样使用 sort 函数 !!!!
int res = 0;
int ed = -2e9;
for (int i = 1; i <= n; i++)
{
if (R[i].l > ed)
{
res++;
ed = R[i].r;
}
}
cout << res << endl;
return 0;
}
解法2:重载 <
运算符
#include <iostream>
#include <algorithm>
using namespace std;
const int N = 100010;
struct range
{
int l, r;
bool operator < (const range& W)const
{
return r < W.r;
}
}R[N];
int main()
{
int n;
cin >> n;
for (int i = 1; i <= n; i++)
{
cin >> R[i].l >> R[i].r;
}
sort(R + 1, R + n + 1);
int res = 0;
int ed = -2e9;
for (int i = 1; i <= n; i++)
{
if (R[i].l > ed)
{
res++;
ed = R[i].r;
}
}
cout << res << endl;
return 0;
}
比较函数
bool cmp(int a, int b)
{
return a > b;
}
- 返回
a<b
为升序排列。 - 返回
a>b
为降序排列。
易错点:
- 比较函数 cmp 的书写。
- 数组下标以 1 开始,
sort
函数使用:sort(n,n+1,cmp)