日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

算法学习:最小圆覆盖

發布時間:2025/7/14 编程问答 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 算法学习:最小圆覆盖 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

【參考博客】

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位技術專家共同創作,文字、視頻、音頻交互閱讀

總結

以上是生活随笔為你收集整理的算法学习:最小圆覆盖的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。