以下摘录复杂度分析
期望O(n2)的张角法
实现的常数爆炸 不开O2就作死
#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<cmath>
using namespace std;
const int N=2005;
const double eps=1e-7;
const double PI=acos(-1.0);
inline int dcmp(double a,double b){
if (fabs(a-b)<eps) return 0;
if (a>b) return 1; return -1;
}
inline double sqr(double x){ return x*x; }
struct Point{
double x,y;
Point(double x=0,double y=0):x(x),y(y) { }
void read(){ scanf("%lf%lf",&x,&y); }
double len(){ return sqrt(x*x+y*y); }
friend Point operator - (Point A,Point B){ return Point(A.x-B.x,A.y-B.y); }
friend double operator * (Point A,Point B){ return A.x*B.x+A.y*B.y; }
friend double Cos(Point A,Point B){
if (A.len()<eps || B.len()<eps) return -1.0;
return A*B/A.len()/B.len();
}
friend double Dis(Point A,Point B){ return (A-B).len(); }
friend double Cross(Point A,Point B){ return A.x*B.y-A.y*B.x; }
}P[N];
inline Point Get(Point a,Point b,Point c){
double a1,a2,b1,b2,c1,c2;
Point ans;
a1=2*(b.x-a.x),b1=2*(b.y-a.y),c1=sqr(b.x)-sqr(a.x)+sqr(b.y)-sqr(a.y);
a2=2*(c.x-a.x),b2=2*(c.y-a.y),c2=sqr(c.x)-sqr(a.x)+sqr(c.y)-sqr(a.y);
if(!dcmp(a1,0)){
ans.y=c1/b1;
ans.x=(c2-ans.y*b2)/a2;
}else if(!dcmp(b1,0)){
ans.x=c1/a1;
ans.y=(c2-ans.x*a2)/b2;
}else{
ans.x=(c2*b1-c1*b2)/(a2*b1-a1*b2);
ans.y=(c2*a1-c1*a2)/(b2*a1-b1*a2);
}
return ans;
}
inline Point Get(Point A,Point B){
return Point((A.x+B.x)/2,(A.y+B.y)/2);
}
int n;
int main(){
freopen("t.in","r",stdin);
freopen("t2.out","w",stdout);
scanf("%d",&n);
for (int i=1;i<=n;i++) P[i].read();
random_shuffle(P+1,P+n+1);
if (n==1){
printf("%.5lf\n%.5lf %.5lf\n",0,P[1].x,P[1].y);
return 0;
}
Point C,c; double R,r;
C=Get(P[1],P[2]); R=Dis(P[1],C);
for (int i=3;i<=n;i++)
if (dcmp(Dis(P[i],C),R)>0){
R=1e130;
for (int j=1;j<i;j++){
int k1=i,k2=i;
for (int k=1;k<i;k++){
if (k==j) continue;
if (Cross(P[j]-P[i],P[k]-P[i])>0){
if (!k1 || Cos(P[j]-P[k],P[i]-P[k])>Cos(P[j]-P[k1],P[i]-P[k1]))
k1=k;
}else{
if (!k2 || Cos(P[j]-P[k],P[i]-P[k])>Cos(P[j]-P[k2],P[i]-P[k2]))
k2=k;
}
}
if (dcmp(acos(Cos(P[j]-P[k1],P[i]-P[k1]))+acos(Cos(P[j]-P[k2],P[i]-P[k2])),PI)>=0){
c=Get(P[i],P[j],P[k1]),r=Dis(c,P[i]);
if (r<R) R=r,C=c;
c=Get(P[i],P[j],P[k2]),r=Dis(c,P[i]);
if (r<R) R=r,C=c;
c=Get(P[i],P[j]),r=Dis(c,P[i]);
if (dcmp(Dis(P[k1],c),r)<=0 && dcmp(Dis(P[k2],c),r)<=0)
if (r<R)
R=r,C=c;
}
}
}
printf("%.5lf\n%.5lf %.5lf\n",R,C.x+eps,C.y+eps);
return 0;
}
期望O(n) 棒极了
1336&1337
#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<cmath>
#define eps 1e-8
#define X first
#define Y second
using namespace std;
typedef pair<double,double> Point;
int n;
Point P[100005],C;
double R;
inline double sqr(double x) { return x*x; }
inline int dcmp(double a,double b)
{
if (fabs(a-b)<eps) return 0;
if (a<b) return -1; return 1;
}
inline double Dist(Point A,Point B)
{
return sqrt((A.X-B.X)*(A.X-B.X)+(A.Y-B.Y)*(A.Y-B.Y));
}
inline Point Get(Point a,Point b,Point c)
{
double a1,a2,b1,b2,c1,c2;
Point ans;
a1=2*(b.X-a.X),b1=2*(b.Y-a.Y),c1=sqr(b.X)-sqr(a.X)+sqr(b.Y)-sqr(a.Y);
a2=2*(c.X-a.X),b2=2*(c.Y-a.Y),c2=sqr(c.X)-sqr(a.X)+sqr(c.Y)-sqr(a.Y);
if(!dcmp(a1,0))
{
ans.Y=c1/b1;
ans.X=(c2-ans.Y*b2)/a2;
}
else if(!dcmp(b1,0))
{
ans.X=c1/a1;
ans.Y=(c2-ans.X*a2)/b2;
}
else
{
ans.X=(c2*b1-c1*b2)/(a2*b1-a1*b2);
ans.Y=(c2*a1-c1*a2)/(b2*a1-b1*a2);
}
return ans;
}
inline Point Get(Point A,Point B)
{
return Point((A.X+B.X)/2,(A.Y+B.Y)/2);
}
inline void MinCover()
{
C=P[1]; R=0;
for(int i=2;i<=n;i++)
if (dcmp(Dist(P[i],C),R)>0)
{
C=P[i];
R=0;
for (int j=1;j<=i;j++)
if (dcmp(Dist(P[j],C),R)>0)
{
C=Get(P[i],P[j]);
R=Dist(C,P[i]);
for (int k=1;k<=j;k++)
if (dcmp(Dist(P[k],C),R)>0)
{
C=Get(P[i],P[j],P[k]);
R=Dist(C,P[i]);
}
}
}
}
int main()
{
freopen("t.in","r",stdin);
freopen("t.out","w",stdout);
scanf("%d",&n);
for (int i=1;i<=n;i++)
scanf("%lf%lf",&P[i].X,&P[i].Y);
MinCover();
printf("%.10lf\n%.10lf %.10lf\n",R,C.X,C.Y);
return 0;
}
2823
#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<cmath>
#define eps 1e-8
#define X first
#define Y second
using namespace std;
typedef pair<double,double> Point;
int n;
Point P[1000005],C;
double R;
inline double sqr(double x) { return x*x; }
inline int dcmp(double a,double b)
{
if (fabs(a-b)<eps) return 0;
if (a<b) return -1; return 1;
}
inline double Dist(Point A,Point B)
{
return sqrt((A.X-B.X)*(A.X-B.X)+(A.Y-B.Y)*(A.Y-B.Y));
}
inline Point Get(Point a,Point b,Point c)
{
double a1,a2,b1,b2,c1,c2;
Point ans;
a1=2*(b.X-a.X),b1=2*(b.Y-a.Y),c1=sqr(b.X)-sqr(a.X)+sqr(b.Y)-sqr(a.Y);
a2=2*(c.X-a.X),b2=2*(c.Y-a.Y),c2=sqr(c.X)-sqr(a.X)+sqr(c.Y)-sqr(a.Y);
if(!dcmp(a1,0))
{
ans.Y=c1/b1;
ans.X=(c2-ans.Y*b2)/a2;
}
else if(!dcmp(b1,0))
{
ans.X=c1/a1;
ans.Y=(c2-ans.X*a2)/b2;
}
else
{
ans.X=(c2*b1-c1*b2)/(a2*b1-a1*b2);
ans.Y=(c2*a1-c1*a2)/(b2*a1-b1*a2);
}
return ans;
}
inline Point Get(Point A,Point B)
{
return Point((A.X+B.X)/2,(A.Y+B.Y)/2);
}
inline void MinCover()
{
C=P[1]; R=0;
for(int i=2;i<=n;i++)
if (dcmp(Dist(P[i],C),R)>0)
{
C=P[i];
R=0;
for (int j=1;j<=i;j++)
if (dcmp(Dist(P[j],C),R)>0)
{
C=Get(P[i],P[j]);
R=Dist(C,P[i]);
for (int k=1;k<=j;k++)
if (dcmp(Dist(P[k],C),R)>0)
{
C=Get(P[i],P[j],P[k]);
R=Dist(C,P[i]);
}
}
}
}
int main()
{
freopen("t.in","r",stdin);
freopen("t.out","w",stdout);
scanf("%d",&n);
for (int i=1;i<=n;i++)
scanf("%lf%lf",&P[i].X,&P[i].Y);
MinCover();
printf("%.2lf %.2lf %.2lf\n",C.X,C.Y,R);
return 0;
}