給出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...