1. 程式人生 > >CODEVS 1214 線段覆蓋 題解

CODEVS 1214 線段覆蓋 題解

size col c代碼 編寫一個程序 main 至少 相互 scrip script

此文為博主原創題解,轉載時請通知博主,並把原文鏈接放在正文醒目位置。

題目鏈接: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 線段覆蓋 題解