FZU Problem 1015 土地劃分

2021-09-20 15:23:55 字數 2595 閱讀 4786

在dukeswood這塊土地上生活著乙個富有的農莊主和他的幾個孩子。在他臨終時,他想把他的土地分給他的孩子。他有許多農場,每個農場都是一塊矩形土地。他在農場地圖上劃上一些直線將矩形分成若干塊。當他划直線時,他總是從矩形邊界上的某一點劃到另乙個矩形邊界上的點,這條線的結束點將成為下一條線的起始點。他劃線時從不會讓任三線共點。例如圖1是某一種劃分結果。

​ 圖1

劃分的起始點和結束點均以五角星標記。當他完成劃分後,他想要數一下劃出的土地的塊數以確保每個孩子都有一塊地。例如,圖1中土地被劃分成18塊。然而這個莊主由於年邁常會數錯,因而他尋求你的幫助。

請寫乙個程式,輸入原來的土地尺寸及線段的位置,輸出劃分出的土地塊數。

輸入檔案有多組資料組成。每組資料格式如下:

第一行輸入地圖的寬度w (1<=w<=1000)和高度 h (1<=h<=1000),均為整數。

第二行輸入線段數l (1<=l<=50)。

以下l+1行每行乙個整數座標(xi,yi),莊主劃的線段為(xi,yi)-(xi+1,yi+1),i=1,2,…,l。當然(xi,yi)必定在矩形的邊界上。

最後一組資料w=h=0,標誌檔案結束,不需要處理。

對於給定的輸入,輸出一行僅含乙個數,即劃分出的土地塊數。

18 12

2 06 12

10 0

18 9

15 12

0 614 0

10 12

0 97 6

2 05 6

7 30 3

3 03 6

0 50 0

結論:平面上n條直線最多可以將平面分成f(n)個區域,其中

f(n)=(n2+n+2)/2

設f(n)為前n條輸入的線段將矩形分成的區域個數,1≤ n ≤ l,l為線段總數。

邊界: f(1) = 2,即一條線段將矩形分成2個區域,如下圖 (a)所示。

遞推:假設現在已經處理了n-1條線段,新線段為l,它和已有的n-1條線段交於t(n)個交點。注意其中有些交點在矩形邊界上,這些交點也是線段的端點,必須將其排除,於是剩下t(n)個交點。如下圖 (b)所示。由於題目中限定「任三線不共點」,因此這些交點將l分成t(n)+1條線段。這t(n)+1條線段將所在區域一分為二,這樣就增加了t(n)+1個區域。

u[1… l]為線段序列,其中u[i]為第i條線段。計算過程如下

t←0;{交點數初始化}

for i←1 to l do{統計l條線段之間的交點個數}

​ for j←i+1 to l do

​ if **u[i]u[j]**相交then t←t+1;

輸出t+l+1;

接下來是如何判斷兩線段是否相交,利用跨立實驗

快速排斥試驗:

設以線段 p1p2 為對角線的矩形為r, 設以線段 q1q2 為對角線的矩形為t,如果r和t不相交,顯然兩線段不會相交。

跨立實驗:

(ps:下面的公式中*代表點積,×代表叉積)

如果兩線段相交,則兩線段必然相互跨立對方。

若p1p2跨立q1q2 ,則向量 ( p1 - q1 ) 和( p2 - q1 )位於向量( q2 - q1 ) 的兩側,

即( p1 - q1 ) × ( q2 - q1 ) * ( p2 - q1 ) × ( q2 - q1 ) < 0。

上式可改寫成( p1 - q1 ) × ( q2 - q1 ) * ( q2 - q1 ) × ( p2 - q1 ) > 0。

所以判斷p1p2跨立q1q2的依據是:( p1 - q1 ) × ( q2 - q1 ) * ( q2 - q1 ) × ( p2 - q1 ) > 0。

同理判斷q1q2跨立p1p2的依據是:( q1 - p1 ) × ( p2 - p1 ) * ( p2 - p1 ) × ( q2 - p1 ) > 0。

看懂這個公式需要掌握的數學知識:向量的叉積和向量的點積。

向量的點積:

給你兩個向量a(ax,by),b(bx,by).

向量a和b的點積公式:a*b=ax*bx+ay*by.

向量的叉積:

給你兩個向量a(ax,by) ,b(bx,by).

向量的叉積公式:a×b=ax*by-ay*bx.

具體請看原文

#include

intmain()

else}}

printf

("%d\n"

, ans);}

return0;

}

FZU Problem 2027 單詞問題

給出乙個完整的句子,這個句子中不包含不可見字元或者空格,於是在這個句子中有許多不同的單詞。乙個單詞是指一串連續的最長的英文本母 大寫或小寫 例如 abc 中,abc 就是乙個單詞,而 ab bc 都不算單詞。輸入包含多組資料 輸入資料第一行是乙個句子,只包含可見字元 不包含空格 句子長度不超過 10...

FZU Problem 2030 括號問題

給出乙個字串,其中包括3種字元 其中?表示這個字元可以是 也可以是 現在給出字串s,你可以在 處填寫 或者 當然隨意填寫得到的序列可能是括號不匹配的。例如 如果你填寫 那麼 是括號不匹配的!現在你的任務是確定你有多少種填寫方案,使得最終的字串是括號匹配的!2種方案是不同的,當2種方案中至少存在1個填...

FZU Problem 2030 括號問題

對於小資料用這dfs,大資料就用遞推的思想。include include include include include include include include include include using namespace std const int maxn 20 char str m...