線段覆蓋長度

2021-09-07 20:07:55 字數 2088 閱讀 4934

不要用桶去計算區間覆蓋的長度,正確的做法是排序後比較區間就好

給定一些線段,線段有起點和終點,求這些線段的覆蓋長度,重複的部分只計算一次。

方法一:

首先說排序對於處理很多問題都是非常有效的,例如尋找兄弟單詞等問題中,經過排序處理後,問題就明朗了很多;

線段覆蓋長度也是這樣,將線段排序後,然後掃瞄一遍就可以得到覆蓋的長度。具體做法:排序時,先按線段的起始端點排序,如果始點相同則按照末端點排,然後從頭掃瞄,尋找連續段;所謂連續段即下一條線段的始點不大於當前線段的末點就一直掃瞄,直到找到斷層的,計算當前長度,然後繼續重複掃瞄直到最後,便得總長度。**如下:

#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將線段放在數軸上,...