题目描述 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 }