乙個空間中存在若干矩形,且矩形的放置方向一致——(矩形的每條邊必然和x或者y軸平行)
求這些矩形覆蓋的總面積的大小。(存在若干個矩形相互重疊的問題)
考慮線段樹可以logn的時間內做到區間覆蓋,區間設定特殊值。因此應當採用線段樹進行計算。
考慮當將矩形切割成兩條形如,x1,x2,y,val的命令,其中x1,x2代表當前上線/下線的長度;y代表當前高度,val取1或-1分別帶至矩形的起始邊和結束邊。
對於當前應用場景,具有很明顯的特點,及,對於任意乙個矩形,都必然將初始邊和結束邊加進線段樹中。則若某給定區間為a,b時,不存在當a,b邊對應的結束邊還未被加進線段樹時就被清零或部分清零的可能性。
因此,對於任意區間,都有顯而易見的兩種狀態:
1,明確的知道該區間已經被填滿。——則區間長度為區間所能表示的上下限之差。
2,不知道該區間是否被填滿。——則區間長度為兩個子區間之差。
對於2情況有乙個子狀態:及當前區間僅僅包含乙個元素:(a == b-1) ——我**中區間定義為左閉右開。對於該區間,若無明確的增加指令,則應當認為區間長度為0。
#includeusingnamespace
std;
#define ll long long
const ll maxn= 1
<<19
;const ll maxm = 2333
;int t,n,sizeofmap =0
;;class
node
;node tree[maxn];
class
command
command(){}
command(
double x1,double x2,double y,int
v)
};command commands[maxm];
int command_number = 0
;void tree_init(int a,int b,int
now)
double
arr[maxm];
int find_pos(double
tar)
void update(int a,int b,int now,int
key)
else tree[now].sum = arr[r]-arr[l];
return
; }
if(a else
update(a,b,rc,key);
if(tree[now].number == 0
)
else tree[now].sum = arr[r]-arr[l];
return
;
}int cases = 1
;void
init()
sort(arr,arr+sizeofmap);
sort(commands,commands+command_number);
tree_init(
0,sizeofmap+2,1
);
double last = 0.0
;
double ans = 0
;
for(int i=0;ii)
double x1 =commands[i].x1;
double x2 =commands[i].x2;
int val =commands[i].val;
update(find_pos(x1),find_pos(x2),
1,val);
}//couttest case #%d\ntotal explored area: %.2f\n\n
",cases++,ans);
}int
main()
return0;
}
掃瞄線演算法
給出幾個矩形對角端點座標,求這些矩形整體覆蓋的面積。基本思想如下圖 先離散化。掃瞄線 是一根想象中的虛線,從左往右掃瞄,遇到 矩形 則成為 事件 遇到 起始邊 則update相應區間的 厚度 或者 覆蓋次數 covercnt 1。遇到 結束邊 則update相應區間的 厚度 covercnt 1。用...
X 掃瞄線演算法
多邊形有兩種重要的表示方法 頂點表示和點陣表示 頂點表示是用多邊形的頂點序列來表示多邊形。這種表示直觀 幾何意義強 佔記憶體少,易於進行幾何變換。但由於它沒有明確指出哪些象素在多邊形內,故不能直接用於面著色 點陣表示是用位於多邊形內的象素集合來刻畫多邊形。這種表示丟失了許多幾何資訊 如邊界 頂點等 ...
高階資料結構之線段樹與掃瞄線演算法
1.掃瞄線演算法 1 原理 平面掃瞄線演算法通常由掃瞄線 事件點 當前掃瞄事件點集合構成 通過掃瞄線按照某一方向依次掃瞄,掃瞄事件點,檢查事件點狀態,然後新增或刪除事件點以更新事件點集合。2 看一道經典的問題 lintcode391.數飛機 給出飛機的起飛和降落時間的列表,用 interval 序列...