這個專題其實不難,但是翻了一圈網上的部落格,寫得是雲裡霧裡,我打算用一篇部落格把它講明白
首先這個掃瞄線演算法解決的是什麼問題? * 主要解決的是acm中的 * 矩形面積問題 * 矩形周長問題 * 多邊形面積問題
這道題最主要就是讓我們求解矩形面積並,求解矩形面積並如果不用任何優化方式,那就是這麼算的。
用矩形和減去矩形交集: $(20-10)(20-10)+(25-15)(25.5-15)-(20-15)*(20-15) = 180.0$ 這樣算非常的耗費時間,因為每個矩形都需要兩兩配對,檢視互相之間是否有交集。
把這兩個矩形分成三個
於是現在就變成了$(20-10)(15-10)+(25.5-10)(20-15)+(25.5-15)*(25-20)=180$
只需要從左往右掃,一步一更新即可
每個新矩形的的高度。
每個新矩形的寬度。
其實計算寬度特簡單。我們把垂直於x的邊單獨挑出來。
然後按照x的大小排個序,隔位相減就可以得到。如$kuan[0] = 15-10; kuan[1] = 20-15;....$
矩形高度怎麼計算呢?這是整個掃瞄線最難理解的地方。
* 很直觀的回答就是:那是因為得算上1號矩形高,再加上2號矩形多出來的部分
* 那是因為得用2號矩形的高那部分減去,減掉2號矩形下面多出來的部分。
這個問題其實也是得到高度最核心的問題,就是「入邊」和「出邊」的問題。
其實所謂的從左往右(也可以是從上往下),就是掃瞄線的方向。當從左往右掃,遇到入邊的線,則對入邊區間掃到進行+1操作,遇到出邊,那麼對出邊區間進行-1操作,這樣子就可以解釋「有時候「多出來」是加上乙個值,有時候「多出來」是減掉乙個值」這個問題了!
(出入邊賦值已完成)
第一條為入邊,區間為[10,20],則區間[10,20] +1(此時區間[10,20] = 1)
檢視整個域的區間,只有[10,20]有值,則kuan[0]*10 = 50
第二條邊為入邊,區間為[15,25.5],則[15,25.5]+1(此時區間[10,15]=1,[15,20]=2,[20,25.5]=1)
檢視整個域區間,從[10,25.5]有值,則kuan[1]*(25.5-10) = 77.5
第三條邊為出邊,區間從[10,20],則[10,20]-1(此時區間為[15,25.5] = 1)
檢視整個區間,從[15,25.5]有值,則kuan[2]*(25.5-15) = 52.5
第四條邊為出邊,區間從[15,25.5],此時-1,整個區間沒掉
整個區間沒值,遍歷結束。
這下整個思路就非常清晰了
我這個下標可存不了25.5這種東西啊,而且它這個區間要是特別大,我的陣列會存不下。
將區間離散化。
把y座標離散化
用乙個區間陣列記錄每個區間的值:於是現在[10,15]成為塊1,[15,20]成為塊2,[20,25.5]成為塊3。
則現在更新第一條入邊[10,20]就變成更新[1,3],更新第二條邊就變成更新[2,4],之後再查表全部乘起來即可
這個和染色問題是一樣的,用乙個cover表示區間[left,right]被覆蓋的次數,用len表示這個區間的合法長度,那query(1到n)的合法長度,自然就能返回總共的區間長度了。
int
根據線段樹的模板,結合這題的樣例,我們很快就建好了一棵樹。
仔細觀察,這棵樹似乎和之前的線段樹不一樣,它的葉子節點的[l,r]不相等,而是差別為1,。 這是因為點對於求面積的題目毫無意義,我們最需要的是它每乙個基礎的「塊」。
第一條為入邊,區間為[1,3],則區間cover[1,3] +1(此時區間[1,3] = 1)
query整個域的區間,得到len=10,則kuan[0]*10 = 50
第二條邊為入邊,區間為[2,4],則cover[2,4]+1(此時如圖所示)
query整個區間,得到len = 15.5,則kuan[1]*(25.5-10) = 77.5
(注意:這裡只需要上推len,不需要下推cover至[2,3]和[3,4],也不需要上推cover至[1,4]。這就是線段樹的強大之處:只要找到對應結點的區間能完全覆蓋當前線段區間就可以回溯統計了,並不需要更新到葉子節點,這是線段樹為什麼效率高的原因)
6. 第三條邊為出邊,區間從[1,3],則[1,3]-1 7.query整個區間,得到10.5,則kuan[2]*10.5 = 52.5
7. 第四條邊為出邊,區間從[15,25.5],此時-1,整個區間沒掉 8. query整個區間,值為0,遍歷結束。
#include
掃瞄線法填充多邊形
如下圖所示多邊形 直線y 1,2,3 8順序掃瞄多邊形,以直線y 3為例,它與多邊形的邊有4個交點,將這4個交點的x座標儲存下來,兩兩之間畫線,也就是 a,b c,d 之間畫線。對於每乙個y都是兩兩之間畫線。現在考慮直線y 2,它與多邊形有3個交點,很顯然是f,g之間畫線,那麼p1怎麼處理呢?可以觀...
多邊形區域填充演算法 掃瞄線種子填充演算法
分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!1.3掃瞄線種子填充演算法 1.1和1.2節介紹的兩種種子填充演算法的優點是非常簡單,缺點是使用了遞迴演算法,這不但需要大量棧空間來儲存相鄰的點,而且效率不高。為了減少演算法中的遞迴呼叫,節省棧空間的使用,人們提出了很多改進演算法,其中一種就是掃瞄...
掃瞄多邊形填充演算法
掃瞄多邊形填充演算法 在做手機地圖的過程中,由於j2me沒提供多邊形填充的api,只能自己實現了,以下是實現的思路,請批評指正 多邊形填充,就是把多邊形所佔據的柵格象素賦予指定的顏色值。要完成這個任務,乙個首要的問題就是求出多邊形所佔據的柵格象素,判斷乙個網格在多邊形內還是多邊形外,在多邊形內的象素...