HDU 4617 Weapon (三维计算几何)

来源:互联网 发布:whatsapp是什么软件 编辑:程序博客网 时间:2024/04/28 20:33

题目地址:http://acm.hdu.edu.cn/showproblem.php?pid=4617


题意:说白了就是求空间上两跳直线的距离 - 两个半径的最小值。


AC代码:

#include <iostream>#include <cstdio>#include <cstring>#include <string>#include <cstdlib>#include <cmath>#include <vector>#include <list>#include <deque>#include <queue>#include <iterator>#include <stack>#include <map>#include <set>#include <algorithm>#include <cctype>#include <ctime>#pragma comment(linker, "/STACK:16777216")using namespace std;typedef __int64 LL;const int N=50005;const int M=55555555;const int INF=0x3f3f3f3f;const double PI=acos(-1.0);const double eps=1e-7;bool zero(double x){    if(fabs(x)<eps)        return true;    return false;}struct point3D{    double x,y,z;    point3D(){};    point3D(double a,double b,double c):x(a),y(b),z(c){}    void input()    {        scanf("%lf%lf%lf",&x,&y,&z);    }    friend point3D operator -(const point3D &a,const point3D &b)    {        return point3D(a.x-b.x,a.y-b.y,a.z-b.z);    }    friend point3D operator +(const point3D &a,const point3D &b)    {        return point3D(a.x+b.x,a.y+b.y,a.z+b.z);    }}p[33][4];double r[33];struct line{    double a,b,c,d;    point3D u,v;}l[33];double vlen(point3D a){    return sqrt(a.x*a.x+a.y*a.y+a.z*a.z);}point3D xmult(point3D u,point3D v){point3D ret;ret.x=u.y*v.z-v.y*u.z;ret.y=u.z*v.x-u.x*v.z;ret.z=u.x*v.y-u.y*v.x;return ret;}double dmult(point3D u,point3D v){    return u.x*v.x+u.y*v.y+u.z*v.z;}point3D get_faline(point3D a,point3D b,point3D c){    return xmult(b-a,c-a);}double xian_xian(line l1,line l2){    point3D n=xmult(l1.u-l1.v,l2.u-l2.v);return fabs(dmult(l1.u-l2.u,n))/vlen(n);}int main(){    int T;    scanf("%d",&T);    while(T--)    {        int n;        scanf("%d",&n);        for(int i=1;i<=n;i++)        {            for(int j=1;j<=3;j++)                p[i][j].input();            r[i]=vlen(p[i][1]-p[i][2]);        }        for(int i=1;i<=n;i++)        {            l[i].u=p[i][1];            l[i].v=p[i][1]+get_faline(p[i][1],p[i][2],p[i][3]);        }        double Min=INF;        int flag=0;        for(int i=1;i<=n;i++)        {            for(int j=i+1;j<=n;j++)            {                double tmp=xian_xian(l[i],l[j]);                tmp-=(r[i]+r[j]);                if(tmp<=0)                {                    flag=1;                    i=j=300;                    break;                }                if(tmp<Min)                    Min=tmp;            }        }        if(flag)            printf("Lucky\n");        else            printf("%.2f\n",Min);    }    return 0;}


原创粉丝点击