算法学习:最小圆覆盖
【參考博客】
https://www.cnblogs.com/bztMinamoto/p/10698920.html
?
?
?
【定義】
【圓】一個圓心和他的半徑,就能夠確定這個半徑
?
【解決問題】
字面意思
給定n個點,求一個直徑最小的能覆蓋所有點的圓
【luogu P1742】
?
?
【算法學習】
最小覆蓋圓上一定會有幾個點,因為這樣才能使結果最優
如果沒有點在圓上,縮小半徑一定是可取的
?
所以我們其實可以直接簡單的循環三次選三個點求其外交圓?
顯然是不行的
?
我們一個一個點向區域中添加,就像凸包一樣
假設我們已經求取出了包含 前 i - 1 點的最小圓
然后添加第 i 個點
如果在圓內,不用管
如果不再圓內,進行以下操作
? 1.? ? 重新確定圓,令 r = 0 ,圓心為這個點
? 2.? ? 然后重新在前 i - 1 個點中找最小覆蓋圓
? 令 j 從1 ~ i - 1 ,把兩個點的連線為直徑做圓
? 3.? ? 再枚舉第三個點,如果這個點在這個新的覆蓋圓外
? 則求三個點的外交圓
這樣一圈枚舉下來就能求出新的最小覆蓋圓了
?
一些細節
如何求三個點最小覆蓋圓
求三個點組成三角形的兩個連線中任意兩條直線的
中垂線的交點即是圓心
中垂線,以直線終點為起點,法線為方向
建直線即可?
?
?
【模板題代碼】
【luogu P1742】
題意如上
?
#include<cstdio> #include<cmath> #include<algorithm> using namespace std; const int MAXN = 1e5 + 5; int n; struct V {double x, y;V() {}V(double a, double b) :x(a), y(b) {}V operator+(const V&b) const { return V(x + b.x , y + b.y);}V operator-(const V&b) const { return V(x - b.x , y - b.y);}double operator*(const V&b) const { return x * b.y - y * b.x; }double operator^(const V&b) const { return x * b.x + y * b.y; }//叉乘V operator*(double b) const { return V(x * b , y*b); }V operator/(double b) const { return V(x / b , y /b); }V rot() { return V(-y, x); }double len() { return (x*x + y * y); } }p[MAXN],o; typedef V P; struct L {V s, t;L(P a,P b):s(a),t(b){}friend P cross(L a, L b) { return a.s + a.t*(b.t*(b.s - a.s)) / (b.t*a.t); }//求交點 }; P circle(P a,P b, P c) {return cross(L((a + b)*0.5, (b - a).rot()), L((a + c)*0.5, (c - a).rot())); } //求圓心 double r; int main() {scanf("%d", &n);for (int i = 1; i <= n; i++){scanf("%lf%lf", &p[i].x, &p[i].y);}random_shuffle(p + 1, p + 1 + n);r = 0, o = P(0 , 0);for (int i = 1; i <= n; i++){if ((p[i] - o).len() > r){o = p[i], r = 0;for(int j=1;j<=i-1;j++)if ((p[j] - o).len() > r){o = (p[i] + p[j])*0.5, r = (p[j] - o).len();for (int k = 1; k <= j - 1; k++)if ((p[k] - o).len() > r)o = circle(p[i], p[j], p[k]), r = (p[k] - o).len();}}}printf("%.10lf\n%.10lf %.10lf", sqrt(r), o.x, o.y);return 0; } View Code?
?
【題目】
【luogu P4586 最小雙圓覆蓋】
【題目大意】n個點,現在給兩個半徑相同的圓去覆蓋,求最小半徑
(多組數據)
【題解】
?
轉載于:https://www.cnblogs.com/rentu/p/11345493.html
《新程序員》:云原生和全面數字化實踐50位技術專家共同創作,文字、視頻、音頻交互閱讀總結
以上是生活随笔為你收集整理的算法学习:最小圆覆盖的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: jQuery UI Autocomple
- 下一篇: 肥宅快乐主席树