题目大意:先确定一个M, 然后输入多组线段的左端和右端的端点坐标,然后让你求出来在所给的线段中能够
把[0, M] 区域完全覆盖完的最少需要的线段数,并输出这些线段的左右端点坐标。
思路分析:
线段区间的起点是0,那么找出所有区间起点小于0中的最合适的区间。
因为需要尽量少的区间,所以选择右端点更大的区间,它包含所选线段更大。
如果在所有区间中找到了解,且右端点小于M,则把找到的区间的右端点定为新的线段区间的起点。
1 #include <iostream>
2 #include <stdio.h>
3 #include <cstring>
4 #include <cmath>
5 #include <algorithm>
6
7
8 using namespace std;
9
10 struct node
11 {
12 int L, R;
13 }a[100010], b[100010];
14
15 bool cmp(node a, node b)
16 {
17 return a.R > b.R;
18 }
19
20 int main()
21 {
22 int M;
23 while(scanf("%d", &M) != EOF)
24 {
25 int Index = 0;
26 while(1)
27 {
28 scanf("%d%d", &a[Index].L, &a[Index].R);
29 if(a[Index].L == 0 && a[Index].R == 0)
30 break;
31 ++Index;
32 }
33
34 sort(a, a+Index, cmp);
35
36 int border = 0; // 起始边界点为0
37 int cnt = 0;
38 while(border < M)
39 {
40 int i = 0;
41 for(; i < Index; ++i)
42 {
43 // a[i].R >= border提交将会Runtime error
44 if(a[i].L <= border && a[i].R > border)
45 {
46 b[cnt] = a[i];
47 cnt++;
48 border = a[i].R; // 更新边界点
49 break;
50 }
51 }
52 if(i == Index)
53 break;
54 }
55
56
57 if(border < M)
58 cout << "No solution" << endl;
59 else
60 {
61 cout << cnt << endl;
62 for(int i = 0; i < cnt; ++i)
63 cout << b[i].L << " " << b[i].R << endl;
64 }
65 }
66
67 return 0;
68 }