CODEVS 1214 线段覆盖 题解

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了CODEVS 1214 线段覆盖 题解相关的知识,希望对你有一定的参考价值。

此文为博主原创题解,转载时请通知博主,并把原文链接放在正文醒目位置。

题目链接:http://codevs.cn/problem/1214/

题目描述 Description

    给定x轴上的N(0<N<100)条线段,每个线段由它的二个端点a_I和b_I确定,I=1,2,……N.这些坐标都是区间(-999,999)的整数。有些线段之间会相互交叠或覆盖。请你编写一个程序,从给出的线段中去掉尽量少的线段,使得剩下的线段两两之间没有内部公共点。所谓的内部公共点是指一个点同时属于两条线段且至少在其中一条线段的内部(即除去端点的部分)。

输入描述 Input Description

    输入第一行是一个整数N。接下来有N行,每行有二个空格隔开的整数,表示一条线段的二个端点的坐标。

输出描述 Output Description

    输出第一行是一个整数表示最多剩下的线段数。

样例输入 Sample Input

3

6  3

1  3

2  5

样例输出 Sample Output

2

数据范围及提示 Data Size & Hint

0<N<100

 

分析:

贪心,把线段按照右端点从小到大排序,每次选取右端点最小且不与已选线段冲突的线段。

显然法可证明

两个注意点:1.输入中左端点的值可能比右端点的值大,需要调换

2.排序时如果右端点相等,按左端点从小到大排序。

我的代码ans记录的是需要删除的线段数量,所以最终输出n-ans

 

AC代码:

 1 #include<iostream>
 2 #include<cstring>
 3 #include<cstdio>
 4 #include<algorithm>
 5 #include<cmath>
 6 #include<queue>
 7  
 8 const int MAXN = 105;
 9  
10 inline void read(int &x)
11 {
12     char ch = getchar(),c = ch;x = 0;
13     while(ch < 0 || ch > 9) c = ch,ch = getchar();
14     while(ch <= 9 && ch >= 0) x = (x<<1)+(x<<3)+ch-0,ch = getchar();
15     if(c == -) x = -x;
16 }
17 
18 int n,ans,last;
19 
20 inline void swap(int &x,int &y)
21 {int t = x;x = y,y = t;}
22 
23 struct LINE
24 {
25     int l,r;
26 }a[MAXN];
27 
28 int cmp(LINE a,LINE b)
29 {
30     if(a.r == b.r)
31         return a.l < b.l;
32     return a.r < b.r;
33 }
34 
35 int main()
36 {
37     read(n);
38     for(int i = 1;i <= n;++ i){
39         read(a[i].l),read(a[i].r);
40         if(a[i].l > a[i].r)
41             swap(a[i].l,a[i].r);
42     }
43     std::sort(a+1,a+1+n,cmp);
44     last = a[1].r;
45     for(int i = 2;i <= n;++ i)
46     {
47         if(a[i].l >= last) last = a[i].r;
48         else ans ++;
49     }
50     printf("%d\n",n-ans);
51     return 0;
52 }

 

以上是关于CODEVS 1214 线段覆盖 题解的主要内容,如果未能解决你的问题,请参考以下文章

codevs 1214线段覆盖

codevs1214 线段覆盖

codevs1214 线段覆盖

20171111 Codevs 1214 线段覆盖

贪心codevs1214:线段覆盖

18.2.27 codevs1214 线段覆盖