POJ 3304 Segments 題解
題目大意:給定若干線段,問是否存在一條直線,使得這些線段在上面的投影有至少一個(gè)公共點(diǎn)。線段以實(shí)數(shù)格式的起點(diǎn)x,起點(diǎn)y,終點(diǎn)x,終點(diǎn)y格式給出。
剛上手的時(shí)候在想n^2內(nèi)的搞法,一看范圍才100條線,暴力完事了
思路:我們考慮題目中那條直線的法線,即垂直于題述直線的一條表示方向的線。每個(gè)線段在直線上的投影相當(dāng)于每個(gè)線段的端點(diǎn)通過這條法線的方向連到直線上形成的兩個(gè)點(diǎn)之間的一個(gè)區(qū)間。

考慮線段間端點(diǎn)的連線,將這條線作為上述的法線,則這兩條線段最終在直線上的投影必定至少有1個(gè)交點(diǎn)。如果這條法線與任何線段都至少有一個(gè)公共點(diǎn),那么可以說明以這條法線為法線的直線至少所有的線段在之上的投影都會(huì)有一個(gè)公共點(diǎn)。
那么我們之間枚舉線段,用兩條不同的線段的兩個(gè)端點(diǎn)分別連線,再去暴力驗(yàn)證是否這條直線穿過所有線段即可。
實(shí)現(xiàn)細(xì)節(jié)比較多,過程中因?yàn)槲覜]有用叉積算相交,所以對(duì)原有板子改造了不少地方。
首先我們需要一個(gè)四舍五入模塊。我們希望精度可以調(diào)一處而動(dòng)全身,所以把這個(gè)參數(shù)寫在命名空間根位置。并且設(shè)置函數(shù)round_compare,把所有涉及實(shí)數(shù)比較的function都改為使用這個(gè)。
向量類與直線類的比較運(yùn)算符需要重寫。
直線類的判斷平行,判斷三點(diǎn)共線需要重寫
為了判斷直線的本質(zhì)相等,我們引入直線歸一化。即把直線一般式的A、B、C看成一個(gè)三維向量,如果他們之間線性相關(guān),則為同一直線。那么我們運(yùn)用向量的單位化于直線的比較。
最后我們需要一個(gè)線段類。這里的線段類派生自直線。
那么核心代碼就可以寫出來了
順便屑站代碼塊是不是有點(diǎn)問題啊,<Segment2>寫不上去?。?/span>