题意:链接
方法:随机增量法
解析:
首先把所有点打乱。
然后枚举第一个点,如果不在当前的圆内则把它设为圆心.
再枚举第二个点,如果不在当前的圆内则把圆设为其与第一个点的距离为直径的圆。
再枚举第三个点,如果不在当前的圆内则把圆设为这三个点构成三角形的外接圆。
然后最后就是答案了。
别问我这为什么是对的- -!
复杂度期望O(n),我是信了。
代码:
#include <cmath>
#include <cstdio>
#include <iomanip>
#include <cstring>
#include <iostream>
#include <algorithm>
#define N 100010
using namespace std;
struct Point
{
double x,y;
friend istream& operator >> (istream &_,Point &a)
{
scanf("%lf%lf",&a.x,&a.y);
return _;
}
Point(){}
Point(double _x,double _y):x(_x),y(_y){}
Point operator + (const Point &a)
{return Point(x+a.x,y+a.y);}
Point operator - (const Point &a)
{return Point(x-a.x,y-a.y);}
Point operator * (double rate)
{return Point(x*rate,y*rate);}
double operator * (const Point &a)
{return x*a.x+y*a.y;}
double operator ^ (const Point &a)
{return x*a.y-y*a.x;}
}pt[N];
struct Line
{
Point p,v;
Line(){}
Line(Point a,Point b):p(a),v(b){}
};
struct Circle
{
Point p;
double R;
Circle(){}
Circle(Point _p,double _R):p(_p),R(_R){}
}ans;
double dis(Point &a,Point &b)
{
return sqrt((a-b)*(a-b));
}
bool is_in_cir(Point &p,Circle &c)
{
return dis(p,c.p)<=c.R;
}
Point Get_Intersection(Line &l1,Line &l2)
{
Point u=l1.p-l2.p;
double tmp=(l2.v^u)/(l1.v^l2.v);
return l1.p+l1.v*tmp;
}
Point rotate (Point a)
{
return Point(-a.y,a.x);
}
int n;
int main()
{
srand(19990329);
scanf("%d",&n);
for(int i=1;i<=n;i++)cin>>pt[i];
random_shuffle(pt+1,pt+n+1);
for(int i=1;i<=n;i++)
{
if(!is_in_cir(pt[i],ans))
{
ans.p=pt[i];
for(int j=1;j<i;j++)
{
if(!is_in_cir(pt[j],ans))
{
ans.p=(pt[i]+pt[j])*0.5;
ans.R=dis(pt[i],pt[j])*0.5;
for(int k=1;k<j;k++)
{
if(!is_in_cir(pt[k],ans))
{
Line l1((pt[i]+pt[j])*0.5,rotate(pt[i]-pt[j]));
Line l2((pt[i]+pt[k])*0.5,rotate(pt[i]-pt[k]));
ans.p=Get_Intersection(l1,l2);
ans.R=dis(ans.p,pt[i]);
}
}
}
}
}
}
cout<<fixed<<setprecision(3)<<ans.R<<endl;
}
版权声明:本文为博主原创文章,未经博主允许不得转载。
时间: 2024-10-13 17:12:22