只会随机增量法
正确性:
显然,这个圆一定是某两个点的外接圆或者某个三角形的外接圆 ,否则就可以变得更小了
时间复杂度 期望是(O(n))
我们先随机生成i个点,求出他们的最小覆盖圆,我们可以认为这个圆是由现在在边界上的那三个点来确定的,也就是说当随机生成的最后一个点不是那三个点时,新生成的点就在圆内,否则在圆外,所以第i个点在前i-1个点的最小覆盖圆外的概率只有3/i
三个点,那么期望就是O(n)咯,但是如果是特殊构造的数据可能卡到(O(n^3))
贴下求三角形外接圆圆心坐标的公式
[left{egin{array}{l}
left(x_{1}-x_{0}
ight)^{2}+left(y_{1}-y_{0}
ight)^{2}=r^{2} (1)\
left(x_{2}-x_{0}
ight)^{2}+left(y_{2}-y_{0}
ight)^{2}=r^{2} (2)\
left(x_{3}-x_{0}
ight)^{2}+left(y_{3}-y_{0}
ight)^{2}=r^{2} (3)
end{array}
ight.
]
1,2相减,1,3相减可以得到
[
egin{array}{l}
left(x_{1}-x_{2}
ight) x_{0}+left(y_{1}-y_{2}
ight) y_{0}=frac{left(x_{1}^{2}-x_{2}^{2}
ight)-left(y_{2}^{2}-y_{1}^{2}
ight)}{2} \
left(x_{1}-x_{3}
ight) x_{0}+left(y_{1}-y_{3}
ight) y_{0}=frac{left(x_{1}^{2}-x_{3}^{2}
ight)-left(y_{3}^{2}-y_{1}^{2}
ight)}{2}
end{array}
]
[egin{array}{l}
a=x_{1}-x_{2} \
b=y_{1}-y_{2} \
c=x_{1}-x_{3} \
d=y_{1}-y_{3} \
e=frac{left(x_{1}^{2}-x_{2}^{2}
ight)-left(y_{2}^{2}-y_{1}^{2}
ight)}{2} \
f=frac{left(x_{1}^{2}-x_{3}^{2}
ight)-left(y_{3}^{2}-y_{1}^{2}
ight)}{2}
end{array}
]
[egin{array}{l}
x_{0}=frac{d e-b f}{b c-a d} \
y_{0}=frac{a f-c e}{b c-a d}
end{array}
]
#include<bits/stdc++.h>
#define rep(i,j,k) for(int i(j);i<=k;++i)
#define drp(i,j,k) for(int i(j);i>=k;--i)
#define repg(x) for(int i(G.head[x]);i;i=G.next[i])
#define bug cout<<"~~~~~~~~~~~~~"<<'
';
using std::cin;
using std::cout;
typedef long long lxl;
template<typename T>
inline T max( T a, T b) {
return a > b ? a : b;
}
template<typename T>
inline T min( T a, T b) {
return a < b ? a : b;
}
std::mt19937 r(std::chrono::system_clock::now().time_since_epoch().count());
const int N = 1e6 + 79;
struct point {
double x, y;
point() {
x = y = 0.0;
}
} t[N], O; //Ô²ÐÄ
inline double dis(const point &rr,const point &r) {
return sqrt( (rr.x - r.x) * (rr.x - r.x) + (rr.y - r.y) * (rr.y - r.y));
}
const double eps = 1e-6;
double R;
inline bool incircle(const point &x) {
return dis(x, O) - R < eps;
}
inline point calc(point p1,point p2,point p3){
double a,b,c,d,e,f;
a=p2.y-p1.y;
b=p3.y-p1.y;
c=p2.x-p1.x;
d=p3.x-p1.x;
f=p3.x*p3.x+p3.y*p3.y-p1.x*p1.x-p1.y*p1.y;
e=p2.x*p2.x+p2.y*p2.y-p1.x*p1.x-p1.y*p1.y;
point ans;
ans.x=(a*f-b*e)/(2*a*d-2*b*c);
ans.y=(d*e-c*f)/(2*a*d-2*b*c);
R=dis(p1,ans);
return ans;
}
int n;
int main() {
std::ios::sync_with_stdio(false);
cin >> n;
rep(i, 1, n) {
cin >> t[i].x >> t[i].y;
}
srand(r());
std::random_shuffle(t + 1, t + n + 1);
O = t[1];
rep(i, 1, n) {
if(incircle(t[i])) continue;
O = t[i];
rep(j, 1, i - 1) {
if(incircle(t[j])) continue;
O.x = (t[i].x + t[j].x) / 2.0;
O.y = (t[i].y + t[j].y) / 2.0;
R = dis(t[i], t[j]) / 2.0;
rep(k, 1, j - 1) {
if(incircle(t[k])) continue;
{
O = calc(t[i], t[j], t[k]);
R = dis(O, t[i]);
}
}
}
}
cout << std::fixed << std::setprecision(10) << R << '
'<< O.x << ' ' << O.y << ' ' ;
return 0;
}