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\n", ans.a, ans.b);
161     }
162     return 0;
163 }

时间: 2024-10-09 06:29:11

uvalive 4973 Ardenia的相关文章

UVALive 4848 Tour Belt

F - Tour Belt Time Limit:3000MS     Memory Limit:0KB     64bit IO Format:%lld & %llu Submit Status Practice UVALive 4848 Description Korea has many tourist attractions. One of them is an archipelago (Dadohae in Korean), a cluster of small islands sca

hdu 4973 A simple simulation problem.(线段树)

http://acm.hdu.edu.cn/showproblem.php?pid=4973 有两种操作 D l r 将[l,r]区间翻倍 Q l r询问[l,r]中相同数字出现的最多次数 比赛的时候脑子太乱了,没有想到怎么做.发现每次翻倍序列的长度都在变化,区间对应的数也在变,没有思路. 但是静下心来想一想,思路还是挺清晰的. 无论怎么翻倍,序列中的数都是连续的,范围是1~n.可以拿一个数组来记录每个数出现的次数,当更新或询问区间[l,r]时,可以利用其前缀和找到区间[l,r]对应的数字分别是

UVALive 6467 Strahler Order 拓扑排序

这题是今天下午BNU SUMMER TRAINING的C题 是队友给的解题思路,用拓扑排序然后就可以了 最后是3A 其中两次RE竟然是因为: scanf("%d",mm); ORZ 以后能用CIN还是CIN吧 QAQ 贴代码了: 1 #include <stdio.h> 2 #include <string.h> 3 #include <stdlib.h> 4 #include <math.h> 5 #include <iostre

UVALive 7077 Little Zu Chongzhi&#39;s Triangles (有序序列和三角形的关系)

这个题……我上来就给读错了,我以为最后是一个三角形,一条边可以由多个小棒组成,所以想到了状态压缩各种各样的东西,最后成功了……结果发现样例过不了,三条黑线就在我的脑袋上挂着,改正了以后我发现N非常小,想到了回溯每个棍的分组,最多分5组,结果发现超时了……最大是5^12 =  244,140,625,厉害呢…… 后来想贪心,首先想暴力出所有可能的组合,结果发现替换问题是一个难题……最后T T ,我就断片了.. 等看了别人的办法以后,我才发现我忽视了三角形的特性,和把数据排序以后的特点. 如果数据从

Gym 100299C &amp;&amp; UVaLive 6582 Magical GCD (暴力+数论)

题意:给出一个长度在 100 000 以内的正整数序列,大小不超过 10^ 12.求一个连续子序列,使得在所有的连续子序列中, 它们的GCD值乘以它们的长度最大. 析:暴力枚举右端点,然后在枚举左端点时,我们对gcd相同的只保留一个,那就是左端点最小的那个,只有这样才能保证是最大,然后删掉没用的. UVaLive上的数据有问题,比赛时怎么也交不过,后来去别的oj交就过了. 代码如下: #pragma comment(linker, "/STACK:1024000000,1024000000&qu

UVALive 6511 Term Project

Term Project Time Limit: 3000ms Memory Limit: 131072KB This problem will be judged on UVALive. Original ID: 651164-bit integer IO format: %lld      Java class name: Main 解题:强连通分量 1 #include <bits/stdc++.h> 2 using namespace std; 3 const int maxn = 1

UVALive 6508 Permutation Graphs

Permutation Graphs Time Limit: 3000ms Memory Limit: 131072KB This problem will be judged on UVALive. Original ID: 650864-bit integer IO format: %lld      Java class name: Main 解题:逆序数 1 #include <bits/stdc++.h> 2 using namespace std; 3 typedef long l

UVALive 2659+HUST 1017+ZOJ 3209 (DLX

UVALive 2659 题目:16*16的数独.试了一发大白模板. /* * @author: Cwind */ //#pragma comment(linker, "/STACK:102400000,102400000") #include <iostream> #include <map> #include <algorithm> #include <cstdio> #include <cstring> #include

UVALive 5545 Glass Beads

Glass Beads Time Limit: 3000ms Memory Limit: 131072KB This problem will be judged on UVALive. Original ID: 554564-bit integer IO format: %lld      Java class name: Main Once upon a time there was a famous actress. As you may expect, she played mostly