题目大意:给两条线段求他们间的最小距离的平方(以分数形式输出)。

贴个模版吧!太抽象了。

#include<cstdio>
#include<cmath>
#include<algorithm>
using namespace std; struct Point3 {
int x, y, z;
Point3(int x=0, int y=0, int z=0):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=0):a(a),b(1) { }
Rat(LL x, LL y):a(x),b(y) {
if(b < 0) a = -a, b = -b;
LL d = gcd(a, b); if(d < 0) 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) < 0) return Length2(v2);
else if(Dot(v1, v3) > 0) 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 == 0) 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 = 0;
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(1000000000);
if(Rat_LineDistance3D(A, B-A, C, D-C, s))
if(s.a > 0 && s.a < s.b && Rat_LineDistance3D(C, D-C, A, B-A, t))
if(t.a > 0 && 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 0;
}

LA 4973异面线段的更多相关文章

  1. [NOIP10.5模拟赛]1.a题解--离散化+异或线段树

    题目链接: 咕咕咕 https://www.luogu.org/problemnew/show/CF817F 闲扯 在Yali经历几天折磨后信心摧残,T1数据结构裸题考场上连暴力都TM没打满 分析 观 ...

  2. CF #365 DIV2 D Mishka and Interesting sum 区间异或+线段树

    D. Mishka and Interesting sum time limit per test 3.5 seconds memory limit per test 256 megabytes in ...

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

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

  4. [数]昨天欠下的一道立体几何题HDU-4741

    并没有做到这道题,后来听学长说了题意,总之就是立体几何嗯 看了好几份题解,是的我知道是异面线段的距离了,可是看码完全不明orz. 这时候出现了一份清晰易懂甚至给出了公式来源的blog╰(*°▽°*)╯ ...

  5. luogu4366 [Code+#4]最短路[优化建边最短路]

    显然这里的$n^2$级别的边数不能全建出来,于是盯住xor这个关键点去 瞎猜 探究有没有什么特殊性质可以使得一些边没有必要建出来. 发现一个点经过一次xor $x$,花费$x$这么多代价(先不看$C$ ...

  6. HDU 3911 线段树区间合并、异或取反操作

    题目:http://acm.hdu.edu.cn/showproblem.php?pid=3911 线段树区间合并的题目,解释一下代码中声明数组的作用: m1是区间内连续1的最长长度,m0是区间内连续 ...

  7. 洛谷 P2574 XOR的艺术(线段树 区间异或 区间求和)

    To 洛谷.2574 XOR的艺术 题目描述 AKN觉得第一题太水了,不屑于写第一题,所以他又玩起了新的游戏.在游戏中,他发现,这个游戏的伤害计算有一个规律,规律如下 1. 拥有一个伤害串为长度为n的 ...

  8. P5283 [十二省联考2019]异或粽子 可持久化01Trie+线段树

    $ \color{#0066ff}{ 题目描述 }$ 小粽是一个喜欢吃粽子的好孩子.今天她在家里自己做起了粽子. 小粽面前有 \(n\) 种互不相同的粽子馅儿,小粽将它们摆放为了一排,并从左至右编号为 ...

  9. 【GDKOI2016Day1T1-魔卡少女】【拆位】线段树维护区间内所有连续子区间的异或和

    题意:给出N个数,M个操作.操作有修改和询问两种,每次修改将一个数改成另一个数,每次询问一个区间的所有连续子区间的异或和.n,m<=100000,ai<=1000 题解: 当年(其实也就是 ...

随机推荐

  1. 博客-从github ghpage 转回通知

    博客迁回 这是我的github博客:http://www.flyfishonline.com/ 原因一 某QQ朋友:"......看了你的简历,根据你(github)博客看,似乎简历包装的过 ...

  2. Objective-C相关Category的收集(更新)

    Categories是给你得不到源码的classes增加功能的一种方法.这个页面收集一些相关的Category,并且持续更新,你可以订阅关注.作者是Fille ?str?m,是@ IMGNRY的联合创 ...

  3. table 会有默认的外边框,内部会有分割线

    .表格中边框的显示 只显示上边框 <table frame=above> 只显示下边框 <table frame=below> 只显示左.右边框 <table frame ...

  4. vue计算属性无法监听到数组内部变化

    计算属性可以帮助我们简化代码,做到实时更新,不用再自己添加function去修改data. 首先看一下计算属性的基本写法(摘自官网) var vm = new Vue({ el: '#demo', d ...

  5. 如何正确入门Windows系统下驱动开发领域?

    [作者]猪头三个人网站 :http://www.x86asm.com/ [序言]很多人都对驱动开发有兴趣,但往往找不到正确的学习方式.当然这跟驱动开发的本土化资料少有关系.大多学的驱动开发资料都以英文 ...

  6. ios之UIButoon

    第一.UIButton的定义 UIButton *button=[[UIButton buttonWithType:(UIButtonType); 能够定义的button类型有以下6种, typede ...

  7. touch-action css属性 滚动和缩放手势

    CSS 属性 touch-action 用于指定某个给定的区域是否允许用户操作,以及如何响应用户操作(比如浏览器自带的划动,缩放等) 默认情况下,平移(滚动) 和 缩放手势由浏览器专门处理.该属性用于 ...

  8. vba练习资料

    链接:https://pan.baidu.com/s/1E0e58rZ_3QCCorWNM-ehSA 提取码:jluf

  9. Bzoj 1085: [SCOI2005]骑士精神 (dfs)

    Bzoj 1085: [SCOI2005]骑士精神 题目链接:https://www.lydsy.com/JudgeOnline/problem.php?id=1085 dfs + 剪枝. 剪枝方法: ...

  10. 条款52:写了placement new 也要写placement delete(write placement delete if you write placement new)

    NOTE: 1.当你写一个placement operator new .请确定也要写出了对应的placement operator delete.如果没有这样做,你的程序可能发生隐晦而时断时续的内存 ...