题意:给出空间两条线段,求距离。

注意输出格式!

 #include<cstdio>
#include<cmath>
#include<algorithm>
using namespace std; struct Point3
{
int x, y, z;
Point3(int x=, int y=, int z=):x(x),y(y),z(z) { }
}; typedef Point3 Vector3; Vector3 operator + (const Vector3& A, const Vector3& B)
{
return Vector3(A.x+B.x, A.y+B.y, A.z+B.z);
}
Vector3 operator - (const Point3& A, const Point3& B)
{
return Vector3(A.x-B.x, A.y-B.y, A.z-B.z);
}
Vector3 operator * (const Vector3& A, int p)
{
return Vector3(A.x*p, A.y*p, A.z*p);
} bool operator == (const Point3& a, const Point3& b)
{
return a.x==b.x && a.y==b.y && a.z==b.z;
} Point3 read_point3()
{
Point3 p;
scanf("%d%d%d", &p.x, &p.y, &p.z);
return p;
} int Dot(const Vector3& A, const Vector3& B)
{
return A.x*B.x + A.y*B.y + A.z*B.z;
}
int Length2(const Vector3& A)
{
return Dot(A, A);
}
Vector3 Cross(const Vector3& A, const Vector3& B)
{
return Vector3(A.y*B.z - A.z*B.y, A.z*B.x - A.x*B.z, A.x*B.y - A.y*B.x);
} typedef long long LL; LL gcd(LL a, LL b)
{
return b ? gcd(b, a%b) : a;
}
LL lcm(LL a, LL b)
{
return a / gcd(a,b) * b;
} struct Rat
{
LL a, b;
Rat(LL a=):a(a),b() { }
Rat(LL x, LL y):a(x),b(y)
{
if(b < ) a = -a, b = -b;
LL d = gcd(a, b);
if(d < ) d = -d;
a /= d;
b /= d;
}
}; Rat operator + (const Rat& A, const Rat& B)
{
LL x = lcm(A.b, B.b);
return Rat(A.a*(x/A.b)+B.a*(x/B.b), x);
} Rat operator - (const Rat& A, const Rat& B)
{
return A + Rat(-B.a, B.b);
}
Rat operator * (const Rat& A, const Rat& B)
{
return Rat(A.a*B.a, A.b*B.b);
} void updatemin(Rat& A, const Rat& B)
{
if(A.a*B.b > B.a*A.b) A.a = B.a, A.b = B.b;
} // 点P到线段AB的距离的平方
Rat Rat_Distance2ToSegment(const Point3& P, const Point3& A, const Point3& B)
{
if(A == B) return Length2(P-A);
Vector3 v1 = B - A, v2 = P - A, v3 = P - B;
if(Dot(v1, v2) < ) return Length2(v2);
else if(Dot(v1, v3) > ) return Length2(v3);
else return Rat(Length2(Cross(v1, v2)), Length2(v1));
} // 求异面直线p1+su和p2+tv的公垂线对应的s。如果平行/重合,返回false
bool Rat_LineDistance3D(const Point3& p1, const Vector3& u, const Point3& p2, const Vector3& v, Rat& s)
{
LL b = (LL)Dot(u,u)*Dot(v,v) - (LL)Dot(u,v)*Dot(u,v);
if(b == ) return false;
LL a = (LL)Dot(u,v)*Dot(v,p1-p2) - (LL)Dot(v,v)*Dot(u,p1-p2);
s = Rat(a, b);
return true;
} void Rat_GetPointOnLine(const Point3& A, const Point3& B, const Rat& t, Rat& x, Rat& y, Rat& z)
{
x = Rat(A.x) + Rat(B.x-A.x) * t;
y = Rat(A.y) + Rat(B.y-A.y) * t;
z = Rat(A.z) + Rat(B.z-A.z) * t;
} Rat Rat_Distance2(const Rat& x1, const Rat& y1, const Rat& z1, const Rat& x2, const Rat& y2, const Rat& z2)
{
return (x1-x2)*(x1-x2)+(y1-y2)*(y1-y2)+(z1-z2)*(z1-z2);
} int main()
{
int T;
scanf("%d", &T);
LL maxx = ;
while(T--)
{
Point3 A = read_point3();
Point3 B = read_point3();
Point3 C = read_point3();
Point3 D = read_point3();
Rat s, t;
bool ok = false;
Rat ans = Rat();
if(Rat_LineDistance3D(A, B-A, C, D-C, s))
if(s.a > && s.a < s.b && Rat_LineDistance3D(C, D-C, A, B-A, t))
if(t.a > && t.a < t.b)
{
ok = true; // 异面直线/相交直线
Rat x1, y1, z1, x2, y2, z2;
Rat_GetPointOnLine(A, B, s, x1, y1, z1);
Rat_GetPointOnLine(C, D, t, x2, y2, z2);
ans = Rat_Distance2(x1, y1, z1, x2, y2, z2);
}
if(!ok) // 平行直线/重合直线
{
updatemin(ans, Rat_Distance2ToSegment(A, C, D));
updatemin(ans, Rat_Distance2ToSegment(B, C, D));
updatemin(ans, Rat_Distance2ToSegment(C, A, B));
updatemin(ans, Rat_Distance2ToSegment(D, A, B));
}
printf("%lld %lld\n", ans.a, ans.b);
}
return ;
}

uvalive 4973 Ardenia的更多相关文章

  1. LA 4973 Ardenia (3D Geometry + Simulation)

    ACM-ICPC Live Archive 三维几何,题意是要求求出两条空间线段的距离.题目难度在于要求用有理数的形式输出,这就要求写一个有理数类了. 开始的时候写出来的有理数类就各种疯狂乱套,TLE ...

  2. UVALive - 4108 SKYLINE[线段树]

    UVALive - 4108 SKYLINE Time Limit: 3000MS     64bit IO Format: %lld & %llu Submit Status uDebug ...

  3. UVALive - 3942 Remember the Word[树状数组]

    UVALive - 3942 Remember the Word A potentiometer, or potmeter for short, is an electronic device wit ...

  4. UVALive - 3942 Remember the Word[Trie DP]

    UVALive - 3942 Remember the Word Neal is very curious about combinatorial problems, and now here com ...

  5. 思维 UVALive 3708 Graveyard

    题目传送门 /* 题意:本来有n个雕塑,等间距的分布在圆周上,现在多了m个雕塑,问一共要移动多少距离: 思维题:认为一个雕塑不动,视为坐标0,其他点向最近的点移动,四舍五入判断,比例最后乘会10000 ...

  6. UVALive 6145 Version Controlled IDE(可持久化treap、rope)

    题目链接:https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&page=show_ ...

  7. UVALive 6508 Permutation Graphs

    Permutation Graphs Time Limit:3000MS     Memory Limit:0KB     64bit IO Format:%lld & %llu Submit ...

  8. UVALive 6500 Boxes

    Boxes Time Limit:3000MS     Memory Limit:0KB     64bit IO Format:%lld & %llu Submit Status Pract ...

  9. UVALive 6948 Jokewithpermutation dfs

    题目链接:UVALive 6948  Jokewithpermutation 题意:给一串数字序列,没有空格,拆成从1到N的连续数列. dfs. 可以计算出N的值,也可以直接检验当前数组是否合法. # ...

随机推荐

  1. c++ 链接

    header.h #ifndef HEADER_H #define HEADER_H unsigned long getFac(unsigned short num); ; #endif // HEA ...

  2. js对象转到字符串

    var str = JSON.stringify(obj);

  3. Firefly安装说明 与 常见问题

    原地址:http://bbs.gameres.com/thread_223688.html 第三方库依赖:    twisted, python-memcached ftp://ftp.tummy.c ...

  4. BZOJ 2806 cheat

    首先这个题目显然是要二分转换成判断可行性的 之后我们考虑DP 设f(i)表示 1->i 熟悉的子串的长度的最大值 那么对于i这个点,要么不在熟悉的子串中,要么在熟悉的子串中 所以得到 f(i)= ...

  5. Git教程之分支管理之一

    分支在实际中有什么用呢? 你创建了一个属于你自己的分支,别人看不到,别人还继续在原来的分支上正常工作,而你在自己的分支上干活,想提交就提交,直到开发完毕后,再一次性合并到原来的分支上,这样,既安全,又 ...

  6. 【转】奇异值分解(We Recommend a Singular Value Decomposition)

    文章转自:奇异值分解(We Recommend a Singular Value Decomposition) 文章写的浅显易懂,很有意思.但是没找到转载方式,所以复制了过来.一个是备忘,一个是分享给 ...

  7. 【HDOJ】4358 Boring counting

    基本思路是将树形结构转线性结构,因为查询的是从任意结点到叶子结点的路径.从而将每个查询转换成区间,表示从该结点到叶子结点的路径.离线做,按照右边界升序排序.利用树状数组区间修改.树状数组表示有K个数据 ...

  8. tcp连接的3次握手

    http://www.tcpipguide.com/free/t_TCPConnectionEstablishmentProcessTheThreeWayHandsh-3.htm synchronou ...

  9. Android开发之极光推送基本步骤

    [转]:http://wyong.blog.51cto.com/1115465/1402842 两天在研究推送的问题,后来确定了用极光推送,本人将整个过程整理一下: 1.到极光官网注册账号:https ...

  10. 【待填坑】bzoj上WC的题解

    之前在bzoj上做了几道WC的题目,现在整理一下 bzoj2115 去膜拜莫队的<高斯消元解xor方程组> bzoj2597 LCT维护MST bzoj1758 分数规划+树分治+单调队列 ...