洛谷 P1742 最小圓覆蓋

2021-10-02 21:04:33 字數 1746 閱讀 3459

給出n個點,讓你畫乙個最小的包含所有點的圓。

這個問題實際上是找出三個點確定的乙個圓,能包含其他所有點。

與三點共圓有密切的關係,先來說三點共圓。

三點共圓有兩種情況:三個點共線或不共線,共線則兩個最遠點構成直徑,不共線則圓為三角形外接圓

重點考慮外接圓情形,班經用正弦定理是比較好找的,其實難度是找圓心,也就是用三角形三個頂點座標來表示外心座標。

下面來談最小圓覆蓋,其實用的是數學歸納法,如果已經覆蓋了前 i 個點,就想辦法造乙個圓讓其覆蓋 i+1 個點。

下面考慮步驟:

1.已知 1 ~ i-1 個點已經由圓ci−

1c_

ci−1

​覆蓋,現在欲加入第 i 個點,讓它也被圓覆蓋

2.如果第 i 個點已經在圓ci−

1c_

ci−1

​中,則下乙個圓 ci=

ci−1

c_i = c_

ci​=ci

−1​,並且回到第一步繼續

3.如果不在,則需要構造新的圓包含 1 ~ i 個點,首先這個新加入的點 i 需要在圓邊上(臨界情況),這也就確定了圓上的乙個點

4.用第乙個點和第 i 個點造圓t1t_

t1​,這時如果有乙個點 j (jt1t_

t1​內,就把它取作c

ic_i

ci​邊上的第二個點。

5.用 i 和 j 兩個點造圓t

2t_2

t2​,同4步,找不在圓t

2t_2

t2​內的點 k (kc

ic_i

ci​邊上的第三個點。

6.現在 i j k 三個點都在圓 c

ic_i

ci​ 上,且能證明 c

ic_i

ci​ 包含了 1~i 所有點,於是用三點共圓構造c

ic_i

ci​,回到1繼續迭代。

迭代到c

nc_n

cn​即結束

這看似是三層迴圈,其實期望複雜度 o(n) ,但為了防止資料不合適,在處理前要先打亂給的 n 個點,用 random_shuffle() 可以實現

#include

#include

#include

#include

#include

#include

using

namespace std;

struct point

point

(double x,

double y):x

(x),

y(y)};

//存點結構體

inline

double

dis(point &p1, point &p2)

//兩個點之間的距離

inline

double

sqr(

double x)

//平方

class

min_circle

void

circular()

//構造圓序列}}

}}} point build_circle

(point a, point b, point c)

elseif(

fabs

(b1-0)

<

1e-8

)else

return ans;

}}mc;

intmain()

洛谷P1742 最小圓覆蓋

給出n個點,讓你畫乙個最小的包含所有點的圓。輸入格式 先給出點的個數n,2 n 100000,再給出座標xi,yi.10000.0 xi,yi 10000.0 輸出格式 輸出圓的半徑,及圓心的座標,保留10位小數 輸入樣例 1 複製 6 8.0 9.0 4.0 7.5 1.0 2.0 5.1 8.7...

P1742 最小圓覆蓋

給出n個點,讓你畫乙個最小的包含所有點的圓。先給出點的個數n,2 n 100000,再給出座標xi,yi.10000.0 xi,yi 10000.0 輸出圓的半徑,及圓心的座標,保留10位小數 6 8.0 9.0 4.0 7.5 1.0 2.0 5.1 8.7 9.0 2.0 4.5 1.05.00...

P1742 最小圓覆蓋(計算幾何)

體驗過 o n 3 過 10 5 嗎?快來體驗一波當 wys 的快感吧 qaq 設 begina1 x b1 y c1 a2 x b2 y c2 end 其中 a1,a2,b1,b2,c1,c2 為已知量 由 式得 x frac 帶入 式並化簡得 y frac 分子分母同時乘以 a2 得 y fra...