题目链接:click.
题意: 给你n个圆,每个圆包括的信息:圆心,圆上的两点,确保三点不成一线.以该圆向两端发射出的射线形成圆柱.
求 若其中有圆柱相交,输出"Lucky"
否则输出最近两个圆柱的距离
解法:
题目已给圆心o,圆上的两点a,b
可以通过向量oa与向量ob的叉积计算出垂直圆面的向量v,
通过o+v得到o’,这样就得到该圆柱体中心轴oo’
枚举每两个圆柱体的中心轴,
计算之间的距离d即可
当d<=line[i].r+line[j].r时即为相交,输出"Lucky"
否则更新最小值ans=min(ans,d-(line[i].r+line[j].r))
代码:
#include<cmath>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int MAXN=1e3+5;
const double EPS=1e-6;
const double PI=acos(-1);
inline int sgn(double a){ return a < -EPS ? -1 : a > EPS; }
inline int cmp(double a, double b){ return sgn(a-b); }
int n,m,T;
struct Point3;
struct Line3;
typedef Point3 Vector3;
struct Point3{
double x,y,z;
Point3(){}
Point3(double a, double b, double c):x(a),y(b),z(c){}
double disToPoint(Point3 p){return sqrt((x-p.x)*(x-p.x)+(y-p.y)*(y-p.y)+(z-p.z)*(z-p.z));}
double len(){return sqrt(x*x+y*y+z*z);}
void read(){scanf("%lf%lf%lf",&x,&y,&z);}
Point3 operator+(Vector3 v){return {x+v.x,y+v.y,z+v.z};}
Vector3 operator-(Point3 p){return {x-p.x,y-p.y,z-p.z};}
Vector3 operator^(Vector3 v){return {y*v.z-z*v.y,z*v.x-x*v.z,x*v.y-y*v.x};}//叉乘
double operator*(Vector3 v){return x*v.x+y*v.y+z*v.z;}//点乘
Vector3 operator*(double d){return {x*d,y*d,z*d};}
Vector3 operator/(double d){return {x/d,y/d,z/d};}
bool operator==(Point3 p){return cmp(x,p.x)==0&&cmp(y,p.y)==0&&cmp(z,p.z)==0;}
bool operator<(Point3 p){if(cmp(x,p.x)==0&&cmp(y,p.y))return z<p.z;else if(cmp(x,p.x))return y<p.y;return x<p.x;}
};
struct Line3{
Line3(){}
Line3(Point3 a,Point3 b,double c=0){s=a,e=b;r=c;}
double disToLine(Line3 v){
Point3 n=((s-e)^(v.s-v.e));
return fabs(((s-v.s)*n))/n.len();
}
Point3 s,e;
double r;
};
Line3 l[55];
void solve(){
double ans=1e9;
for(int i=1;i<=n;i++){
for(int j=i+1;j<=n;j++){
double dis=l[i].disToLine(l[j]);
if(cmp(dis,l[i].r+l[j].r)<=0){
printf("Lucky\n");
return;
}
ans=min(ans,dis-l[i].r-l[j].r);
}
}
printf("%.2lf\n",ans);
}
void init(){
scanf("%d",&n);
Point3 p1,p2,p3;
for(int i=1;i<=n;i++){
p1.read();
p2.read();
p3.read();
l[i]={p1,p1+((p2-p1)^(p3-p1)),p1.disToPoint(p2)};
}
}
int main(){
scanf("%d",&T);
while(T--){
init();
solve();
}
return 0;
}