题目链接:点击进入
题目
题意
n 个点(三维的)位于一个立方体里,你有一个圆锥,只能用一次,只能垂直于平面插入立方体内,问圆锥直径最小为多少时可以将立方体内 n 个点都消灭(碰到)
思路
将n个点分别映射到x-y、x-z、y-z三个平面上,然后求三次最小圆覆盖取最小直径
代码
#include<iostream>
#include<string>
#include<map>
#include<set>
//#include<unordered_map>
#include<queue>
#include<cstdio>
#include<vector>
#include<cstring>
#include<algorithm>
#include<iomanip>
#include<cmath>
#include<fstream>
#define X first
#define Y second
#define best 131
#define INF 0x3f3f3f3f3f3f3f3f
#define pii pair<int,int>
#define lowbit(x) x & -x
#define inf 0x3f3f3f3f
//#define int long long
//#define double long double
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
//const double eps=1e-7;
const double pai=acos(-1.0);
const int N=2e4+10;
const int maxn=1e4+10;
const int mod=1e9+7;
const double eps=1e-12;
struct point{
double x,y,z;
}a[maxn],p[maxn];
double dis(point p,point q){
double x=p.x-q.x,y=p.y-q.y;
return sqrt(x*x+y*y);
}
point circle_center(point a,point b,point c){
double x1=a.x,x2=b.x,x3=c.x;
double y1=a.y,y2=b.y,y3=c.y;
double A=x1*x1+y1*y1,B=x2*x2+y2*y2,C=x3*x3+y3*y3;
double u1=x1-x2,u2=x1-x3,u3=x2-x3;
double v1=y1-y2,v2=y1-y3,v3=y2-y3;
point o;
o.y=((C-A)*u1-(B-A)*u2)/(2*v1*u2-2*v2*u1);
o.x=((C-A)*v1-(B-A)*v2)/(2*u1*v2-2*u2*v1);
return o;
}
int n;double ans=INF;
void solve()
{
point o=a[1];
double r=0;
for(int i=2;i<=n;i++)
{
if(dis(o,a[i])-r>eps)
{
o=a[i];r=0;
for(int j=1;j<i;j++)
{
if(dis(o,a[j])-r>eps)
{
o.x=(a[i].x+a[j].x)/2;
o.y=(a[i].y+a[j].y)/2;
r=dis(o,a[j]);
for(int k=1;k<j;k++)
{
if(dis(o,a[k])-r>eps)
{
o=circle_center(a[i],a[j],a[k]);
r=dis(o,a[k]);
}
}
}
}
}
}
ans=min(ans,r*2.0);
}
int main()
{
// ios::sync_with_stdio(false);
// cin.tie(0);cout.tie(0);
scanf("%d",&n);
for(int i=1;i<=n;i++)
scanf("%lf%lf%lf",&p[i].x,&p[i].y,&p[i].z);
for(int i=1;i<=n;i++)//x y
a[i].x=p[i].x,a[i].y=p[i].y;
random_shuffle(a+1,a+n+1);
solve();
for(int i=1;i<=n;i++)//x z
a[i].x=p[i].x,a[i].y=p[i].z;
random_shuffle(a+1,a+n+1);
solve();
for(int i=1;i<=n;i++)//y z
a[i].x=p[i].y,a[i].y=p[i].z;
random_shuffle(a+1,a+n+1);
solve();
printf("%.10lf",ans);
return 0;
}