zoukankan      html  css  js  c++  java
  • uvalive 4973 Ardenia

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

    注意输出格式!

      1 #include<cstdio>
      2 #include<cmath>
      3 #include<algorithm>
      4 using namespace std;
      5 
      6 struct Point3
      7 {
      8     int x, y, z;
      9     Point3(int x=0, int y=0, int z=0):x(x),y(y),z(z) { }
     10 };
     11 
     12 typedef Point3 Vector3;
     13 
     14 Vector3 operator + (const Vector3& A, const Vector3& B)
     15 {
     16     return Vector3(A.x+B.x, A.y+B.y, A.z+B.z);
     17 }
     18 Vector3 operator - (const Point3& A, const Point3& B)
     19 {
     20     return Vector3(A.x-B.x, A.y-B.y, A.z-B.z);
     21 }
     22 Vector3 operator * (const Vector3& A, int p)
     23 {
     24     return Vector3(A.x*p, A.y*p, A.z*p);
     25 }
     26 
     27 bool operator == (const Point3& a, const Point3& b)
     28 {
     29     return a.x==b.x && a.y==b.y && a.z==b.z;
     30 }
     31 
     32 Point3 read_point3()
     33 {
     34     Point3 p;
     35     scanf("%d%d%d", &p.x, &p.y, &p.z);
     36     return p;
     37 }
     38 
     39 int Dot(const Vector3& A, const Vector3& B)
     40 {
     41     return A.x*B.x + A.y*B.y + A.z*B.z;
     42 }
     43 int Length2(const Vector3& A)
     44 {
     45     return Dot(A, A);
     46 }
     47 Vector3 Cross(const Vector3& A, const Vector3& B)
     48 {
     49     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);
     50 }
     51 
     52 typedef long long LL;
     53 
     54 LL gcd(LL a, LL b)
     55 {
     56     return b ? gcd(b, a%b) : a;
     57 }
     58 LL lcm(LL a, LL b)
     59 {
     60     return a / gcd(a,b) * b;
     61 }
     62 
     63 struct Rat
     64 {
     65     LL a, b;
     66     Rat(LL a=0):a(a),b(1) { }
     67     Rat(LL x, LL y):a(x),b(y)
     68     {
     69         if(b < 0) a = -a, b = -b;
     70         LL d = gcd(a, b);
     71         if(d < 0) d = -d;
     72         a /= d;
     73         b /= d;
     74     }
     75 };
     76 
     77 Rat operator + (const Rat& A, const Rat& B)
     78 {
     79     LL x = lcm(A.b, B.b);
     80     return Rat(A.a*(x/A.b)+B.a*(x/B.b), x);
     81 }
     82 
     83 Rat operator - (const Rat& A, const Rat& B)
     84 {
     85     return A + Rat(-B.a, B.b);
     86 }
     87 Rat operator * (const Rat& A, const Rat& B)
     88 {
     89     return Rat(A.a*B.a, A.b*B.b);
     90 }
     91 
     92 void updatemin(Rat& A, const Rat& B)
     93 {
     94     if(A.a*B.b > B.a*A.b) A.a = B.a, A.b = B.b;
     95 }
     96 
     97 // 点P到线段AB的距离的平方
     98 Rat Rat_Distance2ToSegment(const Point3& P, const Point3& A, const Point3& B)
     99 {
    100     if(A == B) return Length2(P-A);
    101     Vector3 v1 = B - A, v2 = P - A, v3 = P - B;
    102     if(Dot(v1, v2) < 0) return Length2(v2);
    103     else if(Dot(v1, v3) > 0) return Length2(v3);
    104     else return Rat(Length2(Cross(v1, v2)), Length2(v1));
    105 }
    106 
    107 // 求异面直线p1+su和p2+tv的公垂线对应的s。如果平行/重合,返回false
    108 bool Rat_LineDistance3D(const Point3& p1, const Vector3& u, const Point3& p2, const Vector3& v, Rat& s)
    109 {
    110     LL b = (LL)Dot(u,u)*Dot(v,v) - (LL)Dot(u,v)*Dot(u,v);
    111     if(b == 0) return false;
    112     LL a = (LL)Dot(u,v)*Dot(v,p1-p2) - (LL)Dot(v,v)*Dot(u,p1-p2);
    113     s = Rat(a, b);
    114     return true;
    115 }
    116 
    117 void Rat_GetPointOnLine(const Point3& A, const Point3& B, const Rat& t, Rat& x, Rat& y, Rat& z)
    118 {
    119     x = Rat(A.x) + Rat(B.x-A.x) * t;
    120     y = Rat(A.y) + Rat(B.y-A.y) * t;
    121     z = Rat(A.z) + Rat(B.z-A.z) * t;
    122 }
    123 
    124 Rat Rat_Distance2(const Rat& x1, const Rat& y1, const Rat& z1, const Rat& x2, const Rat& y2, const Rat& z2)
    125 {
    126     return (x1-x2)*(x1-x2)+(y1-y2)*(y1-y2)+(z1-z2)*(z1-z2);
    127 }
    128 
    129 int main()
    130 {
    131     int T;
    132     scanf("%d", &T);
    133     LL maxx = 0;
    134     while(T--)
    135     {
    136         Point3 A = read_point3();
    137         Point3 B = read_point3();
    138         Point3 C = read_point3();
    139         Point3 D = read_point3();
    140         Rat s, t;
    141         bool ok = false;
    142         Rat ans = Rat(1000000000);
    143         if(Rat_LineDistance3D(A, B-A, C, D-C, s))
    144             if(s.a > 0 && s.a < s.b && Rat_LineDistance3D(C, D-C, A, B-A, t))
    145                 if(t.a > 0 && t.a < t.b)
    146                 {
    147                     ok = true; // 异面直线/相交直线
    148                     Rat x1, y1, z1, x2, y2, z2;
    149                     Rat_GetPointOnLine(A, B, s, x1, y1, z1);
    150                     Rat_GetPointOnLine(C, D, t, x2, y2, z2);
    151                     ans = Rat_Distance2(x1, y1, z1, x2, y2, z2);
    152                 }
    153         if(!ok)   // 平行直线/重合直线
    154         {
    155             updatemin(ans, Rat_Distance2ToSegment(A, C, D));
    156             updatemin(ans, Rat_Distance2ToSegment(B, C, D));
    157             updatemin(ans, Rat_Distance2ToSegment(C, A, B));
    158             updatemin(ans, Rat_Distance2ToSegment(D, A, B));
    159         }
    160         printf("%lld %lld
    ", ans.a, ans.b);
    161     }
    162     return 0;
    163 }
    View Code
  • 相关阅读:
    从浏览器输入URL到页面渲染的过程
    安全分析的几个好的工具网站的使用
    从一次渗透谈到linux如何反弹shell
    python 进行抓包嗅探
    MYSQL的索引和常见函数
    一篇博客搞定redis基础
    新型横向移动工具原理分析、代码分析、优缺点以及检测方案
    Java反序列化漏洞的挖掘、攻击与防御
    关于Memcached反射型DRDoS攻击分析
    spark未授权RCE漏洞
  • 原文地址:https://www.cnblogs.com/ITUPC/p/4903196.html
Copyright © 2011-2022 走看看