光影切割問題

2021-07-17 06:07:40 字數 2405 閱讀 9362

不少人很愛玩遊戲,例如 cs 。 遊戲設計也成為程式開發的熱點之一,我們假設要設計破舊倉庫之類的場景作為戰爭遊戲的背景。倉庫的地面會因為陽光從屋頂的漏洞或者視窗照射進來而形成許多光照區域和陰影區域。為了簡單起見,假設不同區域的邊界都是直線 , 我們把這些直線都叫做「光影線」,並且不存在三條光影線相交於一點的情況。 

那麼,如果我們需要快速計算某個時刻,在 x 座標[ a, b] 區間的地板上被光影劃分成多少塊。如何才能寫出演算法來計算呢? 

這個問題需要先自己歸納尋找規律。由於不存在三直線交於一點的情況,一些情況可以不用考慮。題目要求的是在a,b區間內,通過嘗試可以找到規律。如果只有一條線,那麼分割成兩塊空間。如果有兩條線,可能相交,也可能不相交(只要在a到b這個區間內不相交就行)。如果相交,那麼就分割成四塊,否則是三塊。

以此類推就會發現,分割塊數=線的數量+在這個區間內的交點數量+1,其中1為區間初始平面個數。

也就是說,只需要判斷在這個區間內的交點有幾個,經過這個區間的線有幾條即可。我們可以先進行一次預處理,計算出所有交點的位置,然後在每一次查詢時就可以很快查詢到了。

進一步分析圖1-12的右圖可以知道,區域內的交點數目就等於乙個邊界上交點順序相對另乙個邊界交點順序的逆序總數(這裡利用到條件「沒有三條直線相交於乙個點」)。在右圖中,左邊界順序為(a,b,c),右邊界為(c,b,a),假設a=1,b=2,c=3,那麼(c,b,a)=(3,2,1),它的逆序數為3。

因此,問題轉化為求乙個n個元素的陣列的逆序數。

最直接的求解逆序數方法還是o(n2),如果用分治的策略可以將時間複雜度降為o(n*log2n),求n個元素的逆序數的分治思想如下,首先求前n/2個元素的逆序數,再求後n/2個元素的逆序數,最後在排序過程中合併前後兩部分之間的逆序數。

解法1:求逆序對

/**

* 光影切割問題

* 尋找逆序數的直接求法

* @author dell

* */

public class revertsortcount1

/*** 直接尋找逆序數

* @return

*/public int count()}}

system.out.println();

return cnt;

}public static void main(string args) ;

revertsortcount1 rsc = new revertsortcount1(a);

system.out.println("逆序數為:"+rsc.count());}}

結果如下:

逆序對為:(5, 4) (3, 2) (5, 2) (4, 2) (8, 2) (8, 6) 

逆序數為:6

解法2:你利用歸併排序

/**

* 光影切割問題

* 尋找逆序數的歸併演算法

* @author dell

* */

public class revertsortcount2

/*** 歸併排序尋找逆序數

* 合併兩個有序陣列

* @param a 待排序陣列

* @param first 第乙個有序陣列在a中的起始位置

* @param mid 第乙個陣列的最後乙個位置

* @param last 第二個陣列的最後乙個位置

*/public void merge(int a, int first, int mid, int last)else

b[k++]=a[j++];

count += mid-i+1; //記錄逆序數}}

while(i<=mid)

while(j<=last)

for(i=first;i<=last;i++)

}/**

* 歸併排序

* @param a 待排序陣列

* @param first 陣列起始位置

* @param last 陣列結束位置

*/public void mergesort(int a, int first, int last)

public static void main(string args) ;

system.out.print("原陣列為:");

for(int i=0;i

原陣列為:3 5 4 8 2 6 9逆序對為:(5, 4) (3, 2) (4, 2) (5, 2) (8, 2) (8, 6)

求逆序數 光影切割問題

程式設計之美 第1.7節,光影切割問題。其中在最後一部分提出了求逆序數的需求,需要在o nlogn 複雜度下計算逆序數。演算法思想 利用歸併排序時左右陣列都已經有序了,例如左邊1,3,5,右邊2,4,6,此時,開始合併,當比較3和2時,由於3 2,因此出現了第乙個逆序數,此時,3後面的數都比2大,因...

程式設計之美 1 7 光影切割問題

1.7 光影切割問題 不少人很愛玩遊戲,例如 cs 遊戲設計也成為程式開發的熱點之一,我們假設要設計破舊倉庫之類的場景作為戰爭遊戲的背景。倉庫的地面會因為陽光從屋頂的漏洞或者視窗照射進來而形成許多光照區域和陰影區域。為了簡單起見,假設不同區域的邊界都是直線 我們把這些直線都叫做 光影線 並且不存在三...

第1章 遊戲之樂 光影切割問題

不少人很愛玩遊戲,例如 cs 遊戲設計也成為程式開發的熱點之一,我們假設要設計破舊倉庫之類的場景作為戰爭遊戲的背景。倉庫的地面會因為陽光從屋頂的漏洞或者視窗照射進來而形成許多光照區域和陰影區域。為了簡單起見,假設不同區域的邊界都是直線 我們把這些直線都叫做 光影線 並且不存在三條光影線相交於一點的情...