【模板】最小圆覆盖(增量法) 洛谷p1742

题目链接:https://www.luogu.org/problem/P1742

打乱之后就是O(n)的了。然后还有个求三角形外接圆的。

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cmath>
 4 #include<algorithm>
 5 #define eps 1e-10
 6 using namespace std;
 7 const int N = 1e5+8;
 8 int n;
 9 struct Point{
10     double x,y;
11     double operator ^ (const Point& b)const{
12         return x*b.y - b.x*y;
13     }
14     Point operator - (const Point& b)const{
15         return (Point){x-b.x,y-b.y};
16     }
17     Point operator + (const Point& b)const{
18         return (Point){x+b.x,y+b.y};
19     }
20     Point operator * (const double b)const{
21         return (Point){b*x,b*y};
22     }
23 }p[N];
24 struct circle{
25     Point o;
26     double r;
27 };
28 int sgn(double x){
29     if(fabs(x) < eps) return 0;
30     if(x<0) return -1;
31     return 1;
32 }
33 double dis(Point u,Point v){
34     return sqrt( (u.x-v.x)*(u.x-v.x) + (u.y-v.y)*(u.y-v.y) );
35 }
36 Point getmid(Point a,Point b){
37     return (Point){(a.x+b.x)/2 , (a.y+b.y)/2};
38 }
39 Point rotate(Point a){return (Point){-a.y,a.x};}
40 Point circlein(Point a,Point b,Point c){
41     Point v1=b-a,v2=a-c; 
42     v1=rotate(v1),v2=rotate(v2);
43     Point p1=getmid(a,b),p2=getmid(a,c);
44     Point u=p1-p2;
45     double t=(v2^u)/(v1^v2);
46     Point oo=p1+v1*t;
47     return oo;
48 }
49 void solve(){
50     circle ans = (circle){p[1],0};
51     for(int i = 2 ; i<=n ; ++i){
52         if( sgn( dis(ans.o,p[i]) - ans.r) > 0 ){
53             ans = (circle){p[i],0};
54             for(int j = 1; j<i ; ++j){
55                 if( sgn( dis(ans.o,p[j]) - ans.r) > 0 ){
56                     ans.o = getmid(p[i],p[j]);
57                     ans.r = dis(p[i],p[j])/2;
58                     for(int k = 1; k < j;++k){
59                         if( sgn( dis(ans.o,p[k]) - ans.r) > 0 ){
60                             ans.o = circlein(p[i],p[j],p[k]);
61                             ans.r = dis(p[i],ans.o); 
62                         }
63                     }
64                 }
65             }
66         }
67     }
68     printf("%.10f\n",ans.r);
69     printf("%.10f %.10f",ans.o.x,ans.o.y);
70 }
71 int main(){
72     scanf("%d",&n);
73     for(int i = 1 ; i <= n ;++i){
74         scanf("%lf%lf",&p[i].x,&p[i].y);
75     }
76     random_shuffle(p+1,p+n+1);
77     solve();
78     return 0;
79 }
View Code

猜你喜欢

转载自www.cnblogs.com/xiaobuxie/p/11621685.html