1214 线段覆盖
时间限制: 1 s
空间限制: 128000 KB
题目等级 : 黄金 Gold
题目描述 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
【题解】
按左端点由小到大排序,从左到右扫过去,优先保留右端点小的。
注意l = r和l > r(mdzz要是知道谁出的题我要把它biao起来)
显然法证明(唔)即可
1 #include <iostream> 2 #include <cstdio> 3 #include <cstdlib> 4 #include <cstring> 5 #include <algorithm> 6 7 inline void read(int &x) 8 { 9 x = 0;char ch = getchar(), c = ch; 10 while(ch < '0' || ch > '9')c = ch, ch = getchar(); 11 while(ch <= '9' && ch >= '0')x = x * 10 + ch - '0', ch = getchar(); 12 if(c == '-')x = -x; 13 } 14 15 inline void swap(int &a, int &b) 16 { 17 int tmp = a;a = b;b = tmp; 18 } 19 20 const int MAXN = 100000 + 10; 21 22 struct Node 23 { 24 int l,r; 25 Node(int _l, int _r){l = _l;r = _r;} 26 Node(){} 27 }node[MAXN]; 28 29 int n; 30 31 bool cmp(Node a, Node b) 32 { 33 return a.l < b.l; 34 } 35 36 int ans, p, tot; 37 38 int main() 39 { 40 read(n); 41 for(register int i = 1;i <= n;++ i) 42 { 43 read(node[i].l), read(node[i].r); 44 if(node[i].l > node[i].r) swap(node[i].l, node[i].r); 45 } 46 std::sort(node + 1, node + 1 + n, cmp); 47 p = 1; 48 for(register int i = 2;i <= n;++ i) 49 if((node[i].l >= node[p].r) || (node[p].r == node[i].l && node[i].l == node[i].r) || (node[p].l == node[p].r && node[i].l == node[p].l)) p = i; 50 else ++ ans, p = node[p].r > node[i].r ? i : p; 51 printf("%d", n - ans); 52 return 0; 53 }