我搜索了很多,但我沒有找到一個適合這種情況的好答案。 我們有一些水平或垂直的矩形。它們可以隨機放置在頁面上。它們可以重疊或具有共同的邊緣或彼此分開。 我想找到一個O(nlogn)算法,可以找到這些矩形的周長和麪積。 這些圖片可能會使問題變得清晰。計算相交矩形的周長和麪積?
我認爲區間樹木可能會有所幫助,但我不知道怎麼樣。
我搜索了很多,但我沒有找到一個適合這種情況的好答案。 我們有一些水平或垂直的矩形。它們可以隨機放置在頁面上。它們可以重疊或具有共同的邊緣或彼此分開。 我想找到一個O(nlogn)算法,可以找到這些矩形的周長和麪積。 這些圖片可能會使問題變得清晰。計算相交矩形的周長和麪積?
我認爲區間樹木可能會有所幫助,但我不知道怎麼樣。
它可以通過掃描線算法完成。
我們將從左到右掃一條想象的線。 我們將注意到直線和矩形集合之間的交集代表一組間隔,並且當我們遇到矩形的左邊緣或右邊緣時它會改變。
假設交叉點在x座標x1和x2之間沒有變化。 然後,如果相交的後X1長度爲大號,線會掃過的區域等於(X2 - X1)* 大號,通過掃描從X1到X2。
例如,你可以看看X1爲左藍線,並X1爲以下圖片右側的藍線(我是從你偷了,並修改了一下:)):
應該清楚,我們的掃描線的交點在這些點之間不會改變。但是,藍色的交叉點與紅色的交叉點完全不同。
我們需要一個數據結構,這些操作:
insert_interval(y1, y2);
get_total_length();
那些很容易用一個段樹實現的,所以我就不贅述了。現在
,算法會是這樣的:
通過離開和右我的意思是一個矩形的邊。
這個想法僅用於計算區域,但是,您可以修改它來計算周長。基本上你會想知道它在某個x座標變化之前和之後的交集長度之間的差異。這個算法的複雜度是O(N log N)(雖然它取決於你可能得到的值的範圍,但這很容易處理)。
你可以在TopCoder上找到更多關於掃描線算法的更多信息。
你可以閱讀關於PEG judge wiki上使用分段樹的各種方法。
這是我的(真的很老的)算法的實現,作爲SPOJ problem NKMARS的解決方案:implementation。
非常感謝。這個算法的時間複雜度是什麼?我認爲這不是O(nlogn).yeah? – CoderInNetwork
是的。我編輯了答案(並且還添加了一個鏈接到我的舊實現)。 – gus
以下是O(N2)解決方案。
int area = 0;
FOR(triange=0->N)
{
Area = area trianlges[triangle];
FOR(int j = triangle+1 -> N)
{
area-= inter(triangle , j)
}
}
return area;
int inter(tri a,tri b)
{
if ((min(a.highY ,b.highY) > max(a.lowerY, b.lowerY)) && (min(a.highX ,b.highX) > max(a.lowerX, b.lowerX)))
return (min(a.highY ,b.highY) - max(a.lowerY, b.lowerY)) * (min(a.highX ,b.highX) - max(a.lowerX, b.lowerX))
else return 0;
}
如果兩個以上的矩形在同一點相交,則這不起作用。 – 2147483647
我的猜測是周邊:) – gus
我想你只能得到一個爲O(n^2)爲最好的結果,因爲你必須檢查一個矩形,其他所有矩形之間的交點,然後計算交叉點的區域和每個區域的邊界,以便您不要將其添加到總和的兩倍。但基本上,您首先需要矩形交點的所有點,以便您知道計算中接下來要移動的位置。 – SoluableNonagon
嘿! yeah perimeter.searching dictionary for finding a good word some times failed。 :) – CoderInNetwork