一:区间选点
题目:
给定N个闭区间[ai,bi],请你在数轴上选择尽量少的点,使得每个区间内至少包含一个选出的点。
输出选择的点的最小数量。
位于区间端点上的点也算作区间内。
输入格式
第一行包含整数N,表示区间数。
接下来N行,每行包含两个整数ai,biai,bi,表示一个区间的两个端点。
输出格式
输出一个整数,表示所需的点的最小数量。
数据范围
1≤N≤1051≤N≤105,
−109≤ai≤bi≤109−109≤ai≤bi≤109
输入样例:
3 -1 1 2 4 3 5
输出样例:
2解析:
代码:

1 #include <bits/stdc++.h>
2 using namespace std;
3
4 const int N = 1e5+10;
5
6 struct Range{
7 int l, r;
8 bool operator < (const Range& t){
9 return r < t.r;
10 }
11 }range[N];
12
13 int main(){
14 int n;cin >> n;
15 for(int i = 0;i < n;++i) cin >> range[i].l >> range[i].r;
16 sort(range, range+n);
17 int ans = 0;
18 int last = -0x3f3f3f3f;
19 for(int i = 0;i < n;++i)
20 if(range[i].l > last){
21 ++ans;
22 last = range[i].r;
23 }
24 cout << ans << endl;
25 return 0;
26 }
二:最大不相交区间数量
题目:
给定N个闭区间[ai,bi],请你在数轴上选择若干区间,使得选中的区间之间互不相交(包括端点)。
输出可选取区间的最大数量。
输入格式
第一行包含整数N,表示区间数。
接下来N行,每行包含两个整数ai,biai,bi,表示一个区间的两个端点。
输出格式
输出一个整数,表示可选取区间的最大数量。
数据范围
1≤N≤1051≤N≤105,
−109≤ai≤bi≤109−109≤ai≤bi≤109
输入样例:
3 -1 1 2 4 3 5
输出样例:
2
分析:

代码:

1 #include <bits/stdc++.h>
2 using namespace std;
3
4 const int N = 1e5+10;
5
6 struct Range{
7 int l, r;
8 bool operator < (const Range& t){
9 return r < t.r;
10 }
11 }range[N];
12
13 int main(){
14 int n;cin >> n;
15 for(int i = 0;i < n;++i) cin >> range[i].l >> range[i].r;
16 sort(range, range+n);
17 int ans = 0;
18 int last = -0x3f3f3f3f;
19 for(int i = 0;i < n;++i)
20 if(range[i].l > last){
21 ++ans;
22 last = range[i].r;
23 }
24 cout << ans << endl;
25 return 0;
26 }
三:区间分组
题目:
给定N个闭区间[ai,bi],请你将这些区间分成若干组,使得每组内部的区间两两之间(包括端点)没有交集,并使得组数尽可能小。
输出最小组数。
输入格式
第一行包含整数N,表示区间数。
接下来N行,每行包含两个整数ai,biai,bi,表示一个区间的两个端点。
输出格式
输出一个整数,表示最小组数。
数据范围
1≤N≤1051≤N≤105,
−109≤ai≤bi≤109−109≤ai≤bi≤109
输入样例:
3 -1 1 2 4 3 5
输出样例:
2分析:
代码:

1 #include <iostream>
2 #include <algorithm>
3 #include <queue>
4 using namespace std;
5
6 const int N = 1e5+10;
7
8 struct Interval{
9 int l, r;
10 bool operator< (const Interval& t){
11 return l < t.l;
12 }
13 }inter[N];
14
15 int main(){
16 int n;cin >> n;
17 for(int i = 1;i <= n;++i) cin >> inter[i].l >> inter[i].r ;
18
19 sort(inter+1, inter+n+1);//按照左端点排序
20
21 priority_queue<int, vector<int>, greater<int>> pq;//存储每一组的max_r
22 for(int i = 1;i <= n;++i){
23 auto t = inter[i];
24 if(pq.empty() || t.l <= pq.top())
25 pq.push(t.r);
26 else{
27 pq.pop();
28 pq.push(t.r);
29 }
30 }
31 cout << pq.size() << endl;
32 return 0;
33 }
四:区间覆盖
题目:
给定N个闭区间[ai,bi]以及一个线段区间[s,t],请你选择尽量少的区间,将指定线段区间完全覆盖。
输出最少区间数,如果无法完全覆盖则输出-1。
输入格式
第一行包含两个整数s和t,表示给定线段区间的两个端点。
第二行包含整数N,表示给定区间数。
接下来N行,每行包含两个整数ai,biai,bi,表示一个区间的两个端点。
输出格式
输出一个整数,表示所需最少区间数。
如果无解,则输出-1。
数据范围
1≤N≤1051≤N≤105,
−109≤ai≤bi≤109−109≤ai≤bi≤109,
−109≤s≤t≤109−109≤s≤t≤109
输入样例:
1 5 3 -1 3 2 4 3 5
输出样例:
2分析:
代码:

1 #include <iostream>
2 #include <algorithm>
3 using namespace std;
4
5 const int N = 1e5+10;
6
7 struct Interval{
8 int l, r;
9 bool operator< (const Interval& t){
10 return l < t.l;
11 }
12 }inter[N];
13
14 int main(){
15 int st, ed;cin >> st >> ed;
16 int n;cin >> n;
17 for(int i = 1;i <= n;++i) cin >> inter[i].l >> inter[i].r;
18
19 sort(inter+1, inter+n+1);
20
21 int ans = 0;
22 for(int i = 1;i <= n;++i){
23 int j = i;
24 int r = -0x3f3f3f3f;
25 //在所有 l <= st 的区间中找到最靠的
26 while(j <= n && inter[j].l <= st){
27 r = max(r, inter[j].r);
28 ++j;
29 }
30 //如果最靠右的小于st无解
31 if(r < st){
32 cout << "-1" << endl;
33 return 0;
34 }
35
36 ++ans;
37
38 if(r >= ed){
39 cout << ans << endl;
40 return 0;
41 }
42
43 st = r;
44 i = j - 1;
45 }
46 cout << -1 << endl;
47 return 0;
48 }
end
来源:https://www.cnblogs.com/sxq-study/p/12343316.html
