区间覆盖

题目链接:http://acm.hust.edu.cn/vjudge/contest/view.action?cid=85904#problem/D

题目:

Given several segments of line (int the X axis) with coordinates [Li; Ri]. You are to choose the minimal

amount of them, such they would completely cover the segment [0; M].
Input
The rst line is the number of test cases, followed by a blank line.
Each test case in the input should contains an integer M (1  M  5000), followed by pairs Li Ri"
(jLi
j; jRi
j  50000, i  100000), each on a separate line. Each test case of input is terminated by pair
`0 0'.
Each test case will be separated by a single line.
Output
For each test case, in the rst line of output your programm should print the minimal number of line
segments which can cover segment [0; M]. In the following lines, the coordinates of segments, sorted
by their left end (Li), should be printed in the same format as in the input. Pair `0 0' should not be
printed. If [0; M] can not be covered by given line segments, your programm should print `0' (without
quotes).
Print a blank line between the outputs for two consecutive test cases.
Sample Input
2


1
-1 0
-5 -3
2 5
0 0


1
-1 0
0 1
0 0


Sample Output
0


1
0 1

题意:

 数轴上有n个闭区间[ai,bi],选择尽量少的区间覆盖一条指定线段[0,m]。

分析:

  贪心法

以0为起点,寻找包含在[0,m]间的最大区间的区间并且把[0,m]区间外的部分切掉,将没有修改前的区间保存到另一个数组中。

再以寻找出的区间的右端点为起点,进行查找。如此循环直到右端点大于等于m时停止。

注意个变量定义的区域

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include <algorithm>
 5 using namespace std;
 6 #define maxn 100010
 7 struct node
 8 {
 9     int l;
10     int r;
11 }a[maxn],b[maxn];
12 int cmp(const node &a, const node &b)                             //按l从小到大排序,当l相同时按r从大到小排序
13 {
14     if(a.l != b.l)    return a.l < b.l;
15     else return a.r > b.r;   
16 }
17 int j,m;
18 int main()
19 {
20 int t;
21 cin>>t;
22 while(t--)
23 {
24     memset(a,0,sizeof(a));
25     memset(b,0,sizeof(b));
26        int i=0;
27     int x,y;
28 cin>>m;
29 while(scanf("%d%d",&x,&y))
30 {
31 if(!x&&!y)  break;
32 a[i].l=x;
33 a[i].r=y;
34 i++;
35 }
36 j=i;
37  sort(a,a+j,cmp);
38  int f,pos;
39  int ma=0,k=0,l=0;
40 while(1)
41  {  
42      if(l>=m)   break;
43       f=0;
44       ma=0;
45      for(i=0;i<j;i++)
46      {
47        if(a[i].l<=l)
48        {
49           if(a[i].r>ma)
50           {
51              pos=i;                     //标记包含区间的位置
52              ma=a[i].r;                     //更改起点
53               f=1;
54           }
55        }
56      }
57    if(f)
58    {
59      l=ma;
60      b[k]=a[pos];
61       k++;
62    }
63    else break;
64 }
65 if(f)
66 {
67     cout<<k<<endl;
68     for(i=0;i<k;i++)
69         cout<<b[i].l<<' '<<b[i].r<<endl;
70 if(t!=0)    cout<<endl;
71 
72 }
73 else  {
74     cout<<'0'<<endl;
75    if(t!=0)  cout<<endl;}
76 }
77 return 0;
78 }

 

原文地址:https://www.cnblogs.com/fenhong/p/4705918.html