最小圓覆蓋是什麼,顧名思義:給出n個點,讓你畫乙個最小的包含所有點的圓,要求出圓的半徑,及圓心的座標。
三點定圓大家都知道吧,唯一要求是三點不共線。
求最小圓,就要列舉這些點,去確定圓。
對於可(du)敬(liu)的出題人,他可不想讓你這麼簡單的做完這個題。
這時,我們就要用到隨機增量法。
用這個東西:random_shuffle(a+1,a+n+1);把出題人善意給你的資料順序打亂。
(你要問為什麼?一會兒會解決吧)
下面我們可以開始求了。三點定圓,當然要三層迴圈,列舉三個點。
對於第乙個點,我們讓其為圓心。對於第二點我們和第乙個點連線,取其中點為圓心.連線為直徑,對於第三個點,我們進行三點定圓.
來了第四個點,我們判斷其是否在圓中,如果在圓中,我們繼續判斷,如果不在圓中,我們取一二個點,和第四個點進行三點定圓.
因為第四個點不在前三個點的圓中.所以第四個點定的新圓一定比前三個定的圓大.
顯然,第三個點的時間複雜度是o(n)的,表面上時間複雜的是o(n^3)
的,實際上在第一次執行完最內層迴圈.已經確定了乙個圓。再執行外邊的兩層迴圈,就會涉及到概率.
均攤時間複雜度o(n),具體我也不會證.
cq(i,2,n)}}
}}
}
前提是三點不共線。
我們設三個點為\((x_1,y_1)\),\((x_2,y_2)\),\((x_3,y_3)\)帶入到方程裡
\[\begin
(x_1−x_0)^2+(y_1−y_0)^2=r^2\\
(x_2−x_0)^2+(y_2−y_0)^2=r^2\\
(x_3−x_0)^2+(y_3−y_0)^2=r^2\\
\end
\]公式(1)(2)相減,(1)(3)相減之後經過化簡可以得到:
\((x_1−x_2)x_0+(y_1−y_2)y_0=\frac\)
\((x_1−x_3)x_0+(y_1−y_3)y_0=\frac\)
上面的式子太複雜,換乙個好看一點的。
設\(a=x_1−x_2\)
\(b=y_1−y_2\)
\(c=x_1−x_3\)
\(d=y_1−y_3\)
\(e=\frac\)
\(f=\frac\)
那麼 解得
de−bf
\(x_0=\frac\)
\(y_0=\frac\)
有了 x_0 和 y_0 的值後,帶入(1) 式就可以得到 r的值。至此,三點確定圓的問題就解決了。
沒了**如下
void tt(point p1,point p2,point p3)
完整**
#include#include#include#include#define cq(i,s,n) for(int i=s;i<=n;i++)
using namespace std;
const double eps=1e-12;
struct pointa[500005];
point o;
int n;
double ri;
double dis(point a,point b)
void tt(point p1,point p2,point p3)
int main()
random_shuffle(a+1,a+n+1);
o=a[1];ri=0;
cq(i,2,n)}}
}}
}printf("%.10lf\n%.10lf %.10lf",ri,o.x,o.y);
return 0;
}
\(}\)(話說可以算成雙倍經驗)
p2533 [ahoi2012]訊號塔
p1742 最小圓覆蓋
最小圓覆蓋
最小圓覆蓋。神奇的隨機演算法。當點以隨機的順序加入時期望複雜度是線性的。algorithm a 令ci表示為前i個點的最小覆蓋圓。當加入新點pi時如果pi不在ci 1裡那麼pi必定在ci的邊界上。b 再從新考慮這樣乙個問題,ci為前i個點最小覆蓋圓且p在ci的的邊界上!同理加入新點pi時如果p i不...
最小圓覆蓋
最小圓覆蓋問題 在乙個平面上,給出 n 個點,求包圍這些點的最小圓,輸出圓心及半徑。分析雖然可以用模擬退火或者三分套三分,這裡只講隨機增量法,隨機增量法是一種確定性演算法,隨機意義下均攤複雜度 o n 而且可以達到很高的精度 可達到 10 10 量級 有事實 如果點 p 不在集合 s 的最小圓覆蓋內...
最小圓覆蓋
本來不想學的 於是今天就碰到一道大裸題 例題 bzoj2823 求最小圓覆蓋n個點。偽 如下 把所有點隨機化,設為 x 1 y 1 x n y n 開始把圓心設為x 1 半徑設為0 for i 2ton 如果i號點在當前圓內則跳過 那麼i號點就在圓周上 把1號點和i號點作為直徑作乙個圓 for j ...