这道题要学一下重载运算符 思路就是如果先按右端点排序 区间有点就过
无点 就加点在区间右端点

[905区间选点] [c++]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
#include<bits/stdc++.h>
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()
{
cin>>n;
for(int i=0;i<n;i++)
{
int l,r;
cin>>l>>r;
range[i]={l,r};
}

sort(range,range+n);

int res=0,ed=-2e9;
for(int i=0;i<n;i++)
{
if(range[i].l>ed)
{
res++;
ed=range[i].r;
}
}
cout<<res<<endl;
return 0;
}

区间分组这道题可以用求最大区间厚度的思想

[区间分组] [c++]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
#include <iostream>
#include <algorithm>

using namespace std;

const int N = 100100;

int n;
int b[2 * N], idx;

int main()
{
scanf ("%d", &n);
for(int i = 0; i < n; i ++)
{
int l, r;
scanf("%d %d", &l, &r);
b[idx ++] = l * 2;//标记左端点为偶数。
b[idx ++] = r * 2 + 1;// 标记右端点为奇数。
}

sort(b, b + idx);

int res = 1, t = 0;
for(int i = 0; i < idx; i ++)
{
if(b[i] % 2 == 0) t ++;
else t --;
res = max(res, t);
}
printf ("%d\n", res);
return 0;
}1

这道题的思路就是 得出每个起点小于st的区间的右端点最大值 再将其更新为st

[区间覆盖] [c++]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
#include<bits/stdc++.h>
using namespace std;
int n;
int st,ed;
const int N=100010;

struct Range
{
int l,r;
bool operator < (const Range &w ) const
{
return l<w.l;
}
}range[N];

int main()
{
bool f=false;
cin>>st>>ed;
cin>>n;
for(int i=0;i<n;i++)
{
int l,r;
cin>>l>>r;
range[i]={l,r};
}
sort(range,range+n);
int res=0;
for(int i=0;i<n;i++) //找每个起点在st左边的区间的右端点的最大值
{
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)
{
f=true;
break;
}
st=r;
i=j-1;
}
if(!f) cout<<-1<<endl;
else cout<<res<<endl;
}


合并果子的思路很简单 就是每次都找最小的两个合并 用堆来维护

[合并果子] [c++]
1
2
3
4
5