列表

详情


NC17378. Rescue

描述

I work at NASA outer space rescue team which needs much courage and patient. In daily life, I always receive a lot of mission, and I must complete it right now. Now I need to build a tunnel to connect two spaceships. In simplicity, let us use a straight line in three dimensional coordinate system to indicate a single spaceship. In order to minimizing the risks, I want to build a tunnel with shortest length.

输入描述

The first line contains an integer T (1 ≤ T ≤ 100000), indicating the number of test cases.
Each case contains two line. The first line contains six integers x1, y1, z1, x2, y2, z2 (-100 ≤ x1,y1,z1,x2,y2,z2 ≤ 100), correspondingly indicating two endpoints of the first spaceship. The second line contains six integers in the same format, describing the second spaceship.

输出描述

For each test cases, output one line indicating the squared length of shortest tunnel. Keep 30 decimal places.

示例1

输入:

2
0 0 0 1 1 1
1 1 1 2 2 2
1 0 0 0 1 0
1 1 0 2 2 0

输出:

0.000000000000000000000000000000
0.500000000000000000000000000000

说明:

Please round to 30 decimal places, without extra spaces.

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

C++14(g++5.4) 解法, 执行用时: 566ms, 内存消耗: 3808K, 提交时间: 2018-08-05 13:39:11

#include<bits/stdc++.h>
#define N 10010
#define LL long long
using namespace std;
struct Point
{
    LL x,y,z;
    Point(LL x=0,LL y=0,LL z=0):x(x),y(y),z(z){};
    void read(){cin>>x>>y>>z;}
};
 
typedef Point Vector;
Vector operator + (Vector a,Vector b){return Vector(a.x+b.x,a.y+b.y,a.z+b.z);}
Vector operator - (Vector a,Vector b){return Vector(a.x-b.x,a.y-b.y,a.z-b.z);}
bool operator == (Vector a,Vector b){return a.x==b.x && a.y==b.y && a.z==b.z;}
LL Dot(Vector a,Vector b){return a.x*b.x+a.y*b.y+a.z*b.z;}  //点积
LL Length(Vector a){return Dot(a,a);}
Vector Cross(Vector a,Vector b) //叉积
{return Vector(a.y*b.z-a.z*b.y,a.z*b.x-a.x*b.z,a.x*b.y-a.y*b.x);}
 
LL z[5][2];
 
void spy(int x,Point p,Point a,Point b)
{
	if(a==b) 
	{
		z[x][0]=Length(p-a);z[x][1]=1;
		return;
	}
    Vector v1=b-a,v2=p-a,v3=p-b;
    if (Dot(v1,v2)<0) {z[x][0]=Length(v2);z[x][1]=1;}else
    if (Dot(v1,v3)>0) {z[x][0]=Length(v3);z[x][1]=1;}else
    {
        z[x][0]=Length(Cross(v1,v2));z[x][1]=Length(v1);
    }
}
 
void print(LL x,LL y)
{
    int a[40];
    cout<<x/y<<".";
    LL t=x%y;
    for (int i=0;i<30;i++)
    {
        t*=10;
        a[i]=t/y;
        t=t%y;
    }
    if(t*10/y>=5)a[29]++;
    int i=29;
    while(a[i]==10) {a[i]=0;a[--i]++;}
    for (int i=0;i<30;i++)cout<<a[i];cout<<endl;
}
 
int main()
{
    int T;
    cin>>T;
    Point a,b,aa,bb;
    while(T--)
    {
        a.read();b.read();aa.read();bb.read();
        Vector n=Cross(a-b,aa-bb);
        Vector p1=Cross(b-a,n),p2=Cross(bb-aa,n);
        if (Dot(aa-a,p1)*Dot(bb-a,p1)<0 && Dot(a-aa,p2)*Dot(b-aa,p2)<0)
        {
            Vector v=Cross(a-b,aa-bb);
            if (Length(v)==0)
            {
                cout<<"0.000000000000000000000000000000"<<endl;
            }else
            {
                LL ff=Dot(a-aa,v);
                LL n=Length(v);
                print(ff*ff,n);
            }
        }else
        {
            spy (1,a,aa,bb);
            spy (2,b,aa,bb);
            spy (3,aa,a,b);
            spy (4,bb,a,b);
            for (int i=2;i<=4;i++)
            {
                if (z[1][0]*z[i][1]>z[1][1]*z[i][0])
                {
                    swap(z[1][0],z[i][0]);
                    swap(z[1][1],z[i][1]);
                }
            }
            print(z[1][0],z[1][1]);
        }
    }
 
    return 0;
}

C++11(clang++ 3.9) 解法, 执行用时: 567ms, 内存消耗: 3672K, 提交时间: 2018-08-05 16:47:59

#include<bits/stdc++.h>
#define LL long long
using namespace std;
struct Point
{
    LL x,y,z;
    Point(LL x=0,LL y=0,LL z=0):x(x),y(y),z(z){};
    void read(){cin>>x>>y>>z;}
};
typedef Point Vector;
Vector operator + (Vector a,Vector b){return Vector(a.x+b.x,a.y+b.y,a.z+b.z);}
Vector operator - (Vector a,Vector b){return Vector(a.x-b.x,a.y-b.y,a.z-b.z);}
bool operator == (Vector a,Vector b){return a.x==b.x && a.y==b.y && a.z==b.z;}
LL Dot(Vector a,Vector b){
    return a.x*b.x+a.y*b.y+a.z*b.z;
}  
LL Length(Vector a){
    return Dot(a,a);
}
Vector Cross(Vector a,Vector b){
    return Vector(a.y*b.z-a.z*b.y,a.z*b.x-a.x*b.z,a.x*b.y-a.y*b.x);
}
LL z[5][2];
void sp(int x,Point p,Point a,Point b)
{
	if(a==b) 
	{
		z[x][0]=Length(p-a);z[x][1]=1;
		return;
	}
    Vector v1=b-a,v2=p-a,v3=p-b;
    if (Dot(v1,v2)<0) {z[x][0]=Length(v2);z[x][1]=1;}else
    if (Dot(v1,v3)>0) {z[x][0]=Length(v3);z[x][1]=1;}else
    {
        z[x][0]=Length(Cross(v1,v2));z[x][1]=Length(v1);
    }
}
void print(LL x,LL y)
{
    int a[40];
    cout<<x/y<<".";
    LL t=x%y;
    for (int i=0;i<30;i++)
    {
        t*=10;
        a[i]=t/y;
        t=t%y;
    }
    if(t*10/y>=5)a[29]++;
    int i=29;
    while(a[i]==10) {a[i]=0;a[--i]++;}
    for (int i=0;i<30;i++)cout<<a[i];cout<<endl;
}
int main()
{
    int T;
    cin>>T;
    Point a,b,aa,bb;
    while(T--)
    {
        a.read();b.read();aa.read();bb.read();
        Vector n=Cross(a-b,aa-bb);
        Vector p1=Cross(b-a,n),p2=Cross(bb-aa,n);
        if (Dot(aa-a,p1)*Dot(bb-a,p1)<0 && Dot(a-aa,p2)*Dot(b-aa,p2)<0)
        {
            Vector v=Cross(a-b,aa-bb);
            if (Length(v)==0)
            {
                cout<<"0.000000000000000000000000000000"<<endl;
            }else
            {
                LL ff=Dot(a-aa,v);
                LL n=Length(v);
                print(ff*ff,n);
            }
        }else
        {
            sp (1,a,aa,bb);
            sp (2,b,aa,bb);
            sp (3,aa,a,b);
            sp (4,bb,a,b);
            for (int i=2;i<=4;i++)
            {
                if (z[1][0]*z[i][1]>z[1][1]*z[i][0])
                {
                    swap(z[1][0],z[i][0]);
                    swap(z[1][1],z[i][1]);
                }
            }
            print(z[1][0],z[1][1]);
        }
    }
    return 0;
}

上一题