不要用桶去計算區間覆蓋的長度,正確的做法是排序後比較區間就好
給定一些線段,線段有起點和終點,求這些線段的覆蓋長度,重複的部分只計算一次。
方法一:
首先說排序對於處理很多問題都是非常有效的,例如尋找兄弟單詞等問題中,經過排序處理後,問題就明朗了很多;
線段覆蓋長度也是這樣,將線段排序後,然後掃瞄一遍就可以得到覆蓋的長度。具體做法:排序時,先按線段的起始端點排序,如果始點相同則按照末端點排,然後從頭掃瞄,尋找連續段;所謂連續段即下一條線段的始點不大於當前線段的末點就一直掃瞄,直到找到斷層的,計算當前長度,然後繼續重複掃瞄直到最後,便得總長度。**如下:
#includeusing namespace std;
/* 排序求線段覆蓋長度 */
#define maxn 100 // 設線段數不超過100
struct segment
segarr[100];
/* 計算線段覆蓋長度 */
int lencount(segment * segarr, int size)
length += (end - start);
} return length;
}/* 快排比較函式 */
int cmp(const void * p, const void *q)
return ((segment *)p)->end - ((segment *)q)->end;
}/* 測試線段 answer: 71 */
int segtest[10][2] = ;
void main()
qsort(segarr,10,sizeof(segment),cmp); // 排序
printf("length: %d\n",lencount(segarr,10)); // 計算
}
方法二:
#includeusing namespace std;
/* 線段樹求線段覆蓋長度 */
#define border 100 // 設線段端點座標不超過100
struct node // 線段樹
segtree[4*border];
/* 構建線段樹 根節點開始構建區間[lef,rig]的線段樹*/
void construct(int index, int lef, int rig)
int mid = (lef+rig) >> 1;
construct((index<<1)+1, lef, mid);
construct((index<<1)+2, mid, rig); // 非mid+1,線段覆蓋[mid,mid+1]
segtree[index].iscover = 0;
}/* 插入線段[start,end]到線段樹, 同時標記覆蓋 */
void insert(int index, int start, int end)
int mid = (segtree[index].left + segtree[index].right) >> 1;
if(end <= mid)
else if(start >= mid) // 勿漏=
else }
/* 計算線段覆蓋長度 */
int count(int index)
else if(segtree[index].right - segtree[index].left == 1)
return count((index<<1)+1) + count((index<<1)+2);
}/* 測試線段 answer: 71 */
int segment[10][2] = ;
void main()
printf("the cover length is %d\n", count(0));
}
總結:
基於排序的方法,由於排序的緣故,複雜度為o(nlgn);使用線段樹時,因其查詢和插入操作都可以在lgn的時間完成,故對於所有線段完成插入,最後查詢長度,演算法總的複雜度也是o(nlgn)級別。
參考:線段覆蓋長度 - 花開無言 - csdn部落格
線段樹線段覆蓋(離散化 區間覆蓋)
n n 10000 個人依次貼海報,給出每張海報所貼的範圍li,ri 1 li ri 10000000 求出最後還能看見多少張海報。input 第一行 樣例個數t 第二行 貼海報的人n 第三行 每個人貼海報的範圍 接下來n行 每個人貼海報的範圍 output 對於每乙個輸入,輸出最後可以看到的海報張...
1214 線段覆蓋
貪心解法 解題思路 首先將線段端點調整為左端點小於 或等於 右端點 第二,根據右端點將線段從小到大排序 第三,掃瞄一遍,每次遇到的第乙個與當前的max不相交的即為最優選擇。實現 include includeusing namespace std const int n 101 struct nod...
線段覆蓋問題
題目描述 n e最近在研究線段覆蓋問題。n e有n條線段和 個數軸,數軸 限長,每條線段在數軸上都有 個固定起點si和固定終點ei,其中si和ei都是整數。放在數軸上的線段不能重合,不能重合定義為 對於兩條不同線段 不妨設為第i條和第j條 定要滿 si ej或ei sj。現在n e將線段放在數軸上,...