题目大意:先确定一个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 }