1、区间合并
Acwing803. 区间合并
给定
n
n
n 个区间
[
l
i
,
r
i
]
[l_i,r_i]
[li,ri],要求合并所有有交集的区间。
注意如果在端点处相交,也算有交集。
输出合并完成后的区间个数。
例如: [ 1 , 3 ] [1,3] [1,3] 和 [ 2 , 6 ] [2,6] [2,6] 可以合并为一个区间 [ 1 , 6 ] [1,6] [1,6]。
输入格式
第一行包含整数
n
n
n。
接下来 n n n 行,每行包含两个整数 l l l 和 r r r。
输出格式
共一行,包含一个整数,表示合并区间完成后的区间个数。
数据范围
1
≤
n
≤
100000
1\leq n\leq100000
1≤n≤100000,
−
1
0
9
≤
l
i
≤
r
i
≤
1
0
9
−10^9\leq l_i\leq r_i\leq10^9
−109≤li≤ri≤109
输入样例:
5
1 2
2 4
5 6
7 8
7 9
输出样例:
3
#include<bits/stdc++.h>
using namespace std;
#define x first
#define y second
typedef pair<int, int> PII;
int n;
vector<PII> nums,res;
int main()
{
scanf("%d", &n);
for(int i = 0 ;i < n ;i ++){
int a,b;
scanf("%d%d", &a, &b);
nums.push_back({a,b});
}
sort(nums.begin(),nums.end());
for(int i =0 ,j =1 ; i < n ; ){
int r = nums[i].y;
while(j <n && nums[j].x<=r){
r = max(r,nums[j].y);
j++;
}
res.push_back({nums[i].x,r});
i = j ;
j++;
}
// for(auto a:res){
// printf("%d %d \n",a.x,a.y);
// }
printf("%d",res.size());
return 0;
}
2、区间选点
Acwing905. 区间选点
给定
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
#include<bits/stdc++.h>
using namespace std;
const int N = 1e5+10;
struct Range{
int l,r;
bool operator < (const Range & w) const{
return r < w.r;
}
}range[N];
int main()
{ int n;
scanf("%d", &n);
for (int i = 0; i < n; i ++ ){
scanf("%d%d", &range[i].l,&range[i].r);
}
sort(range,range+n);
int res = 0 ,ed = -2e9;
for(int i = 0 ;i <n ;i++ ){
if(ed < range[i].l){
res ++;
ed = range[i].r;
}
}
printf("%d\n",res);
return 0;
}
3、最大不相交区间数量
AcWing 908. 最大不相交区间数量
给定
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
参考代码
#include <iostream>
#include <algorithm>
using namespace std;
const int N = 100010;
int n;
struct Range
{
int l, r;
bool operator< (const Range &W)const
{
return r < W.r;
}
}range[N];
int main()
{
scanf("%d", &n);
for (int i = 0; i < n; i ++ ) scanf("%d%d", &range[i].l, &range[i].r);
sort(range, range + n);
int res = 0, ed = -2e9;
for (int i = 0; i < n; i ++ )
if (ed < range[i].l)
{
res ++ ;
ed = range[i].r;
}
printf("%d\n", res);
return 0;
}
4、区间分组
Acwing906. 区间分组
给定
N
N
N 个闭区间
[
a
i
,
b
i
]
[a_i,b_i]
[ai,bi],请你将这些区间分成若干组,使得每组内部的区间两两之间(包括端点)没有交集,并使得组数尽可能小。
输出最小组数。
输入格式
第一行包含整数
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\leq10^9
−109≤ai≤bi≤109
输入样例:
3
-1 1
2 4
3 5
输出样例:
2
#include<bits/stdc++.h>
using namespace std;
const int N = 1e5+10;
struct Range{
int l,r;
bool operator < (const Range & W) const {
return l <W.l;
}
}range[N];
int n;
int main()
{
scanf("%d", &n);
for(int i = 0 ;i < n ;i ++){
int x,y;
scanf("%d%d", &x, &y);
range[i] = {x,y};
}
priority_queue<int,vector<int>,greater<int> > heap;
sort(range,range+n);
for(int i = 0 ;i < n ;i ++){
if(heap.empty() || heap.top() >= range[i].l) heap.push(range[i].r);
else{
heap.pop();
heap.push(range[i].r);
}
}
printf("%d\n",heap.size());
return 0;
}
5、区间覆盖
给定 N N N 个闭区间 [ a i , b i ] [a_i,b_i] [ai,bi],请你将这些区间分成若干组,使得每组内部的区间两两之间(包括端点)没有交集,并使得组数尽可能小。
输出最小组数。
输入格式
第一行包含整数
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\leq10^9
−109≤ai≤bi≤109
输入样例:
1 5
3
-1 3
2 4
3 5
输出样例:
2
参考代码
#include<bits/stdc++.h>
using namespace std;
const int N = 1e5+10;
struct Range{
int l,r;
bool operator < (const Range &W) const {
return l<W.l;
}
}range[N];
int n;
int main(){
int st ,ed;
scanf("%d%d", &st, &ed);
scanf("%d", &n);
for(int i = 0 ;i < n; i ++){
int x,y ;
scanf("%d%d", &x, &y);
range[i] = {x,y};
}
sort(range,range+n);
bool flag = false;
int res = 0 ;
for(int i = 0 ;i < n; i++){
int j = i , r = -2e9;
while(j < n && range[j].l<=st){
r = max(r,range[j].r);
j++;
}
if(r < st){
res = - 1;
break;
}
res ++ ;
if(r>=ed){
flag = true;
break;
}
st = r;
i = j -1;
}
printf("%d",flag?res:-1);
return 0;
}