LA 4973 Ardenia (3D Geometry + Simulation)
三维几何,题意是要求求出两条空间线段的距离。题目难度在于要求用有理数的形式输出,这就要求写一个有理数类了。
开始的时候写出来的有理数类就各种疯狂乱套,TLE的结果是显然的。后来发现,在计算距离前都是不用用到有理数类的,所以就将开始的部分有理数改成直接用long long。其实好像可以用int来做的,不过我的方法比较残暴,中间运算过程居然爆int了。所以就只好用long long了。
代码如下,附带debug以及各种强的数据:
#include <cstdio>
#include <iostream>
#include <cstring>
#include <algorithm>
#include <cmath> using namespace std; template<class T> T gcd(T a, T b) { return b ? gcd(b, a % b) : a;}
template <class T> T sqr(T x) { return x * x;}
typedef long long LL;
struct Rat {
LL a, b;
Rat() {}
Rat(LL x) { a = x, b = ;}
Rat(LL _a, LL _b) {
LL GCD = gcd(_b, _a);
a = _a / GCD, b = _b / GCD;
}
double val() { return (double) a / b;}
bool operator < (Rat x) const { return a * x.b < b * x.a;}
bool operator > (Rat x) const { return a * x.b > b * x.a;}
bool operator == (Rat x) const { return a * x.b == b * x.a;}
bool operator < (LL x) const { return Rat(a, b) < Rat(x);}
bool operator > (LL x) const { return Rat(a, b) > Rat(x);}
bool operator == (LL x) const { return Rat(a, b) == Rat(x);}
Rat operator + (Rat x) {
LL tb = b * x.b, ta = a * x.b + b * x.a;
LL GCD = gcd(abs(tb), abs(ta));
return Rat(ta / GCD, tb / GCD);
}
Rat operator - (Rat x) {
LL tb = b * x.b, ta = a * x.b - b * x.a;
LL GCD = gcd(abs(tb), abs(ta));
return Rat(ta / GCD, tb / GCD);
}
Rat operator * (Rat x) {
if (a * x.a == ) return Rat(, );
// if (b * x.b == 0) { puts("..."); while (1) ;}
LL tb = b * x.b, ta = a * x.a;
LL GCD = gcd(abs(tb), abs(ta));
return Rat(ta / GCD, tb / GCD);
}
Rat operator / (Rat x) {
if (a * x.b == ) return Rat(, );
// if (b * x.a == 0) { puts("!!!"); while (1) ;}
LL GCD, tb = b * x.a, ta = a * x.b;
GCD = gcd(abs(tb), abs(ta));
return Rat(ta / GCD, tb / GCD);
}
void fix() {
a = abs(a), b = abs(b);
LL GCD = gcd(b, a);
a /= GCD, b /= GCD;
}
} ; struct Point {
LL x[];
Point operator + (Point a) {
Point ret;
for (int i = ; i < ; i++) ret.x[i] = x[i] + a.x[i];
return ret;
}
Point operator - (Point a) {
Point ret;
for (int i = ; i < ; i++) ret.x[i] = x[i] - a.x[i];
return ret;
}
Point operator * (LL p) {
Point ret;
for (int i = ; i < ; i++) ret.x[i] = x[i] * p;
return ret;
}
bool operator == (Point a) const {
for (int i = ; i < ; i++) if (!(x[i] == a.x[i])) return false;
return true;
}
void print() {
for (int i = ; i < ; i++) cout << x[i] << ' ';
cout << endl;
}
} ;
typedef Point Vec; struct Line {
Point s, t;
Line() {}
Line (Point s, Point t) : s(s), t(t) {}
Vec vec() { return t - s;}
} ;
typedef Line Seg; LL dotDet(Vec a, Vec b) {
LL ret = ;
for (int i = ; i < ; i++) ret = ret + a.x[i] * b.x[i];
return ret;
} Vec crossDet(Vec a, Vec b) {
Vec ret;
for (int i = ; i < ; i++) {
ret.x[i] = a.x[(i + ) % ] * b.x[(i + ) % ] - a.x[(i + ) % ] * b.x[(i + ) % ];
}
return ret;
} inline LL vecLen(Vec x) { return dotDet(x, x);}
inline bool parallel(Line a, Line b) { return vecLen(crossDet(a.vec(), b.vec())) == ;}
inline bool onSeg(Point x, Point a, Point b) { return parallel(Line(a, x), Line(b, x)) && dotDet(a - x, b - x) < ;}
inline bool onSeg(Point x, Seg s) { return onSeg(x, s.s, s.t);} Rat pt2Seg(Point p, Point a, Point b) {
if (a == b) return Rat(vecLen(p - a));
Vec v1 = b - a, v2 = p - a, v3 = p - b;
if (dotDet(v1, v2) < ) return Rat(vecLen(v2));
else if (dotDet(v1, v3) > ) return Rat(vecLen(v3));
else return Rat(vecLen(crossDet(v1, v2)), vecLen(v1));
}
inline Rat pt2Seg(Point p, Seg s) { return pt2Seg(p, s.s, s.t);}
inline Rat pt2Plane(Point p, Point p0, Vec n) { return Rat(sqr(dotDet(p - p0, n)), vecLen(n));}
inline bool segIntersect(Line a, Line b) {
Vec v1 = crossDet(a.s - b.s, a.t - b.s);
Vec v2 = crossDet(a.s - b.t, a.t - b.t);
Vec v3 = crossDet(b.s - a.s, b.t - a.s);
Vec v4 = crossDet(b.s - a.t, b.t - a.t);
// v1.print();
// v2.print();
// cout << dotDet(v1, v2).val() << "= =" << endl;
return dotDet(v1, v2) < && dotDet(v3, v4) < ;
}// cout << "same plane" << endl; pair<Rat, Rat> getIntersect(Line a, Line b) {
Point p = a.s, q = b.s;
Vec v = a.vec(), u = b.vec();
LL uv = dotDet(u, v), vv = dotDet(v, v), uu = dotDet(u, u);
LL pv = dotDet(p, v), qv = dotDet(q, v), pu = dotDet(p, u), qu = dotDet(q, u);
if (uv == ) return make_pair(Rat(qv - pv, vv), Rat(pu - qu, uu));
// if (vv == 0 || uv == 0 || uv / vv - uu / uv == 0) { puts("shit!"); while (1) ;}
Rat y = (Rat(pv - qv, vv) - Rat(pu - qu, uv)) / (Rat(uv, vv) - Rat(uu, uv));
Rat x = (y * uv - pv + qv) / vv;
// cout << x.a << ' ' << x.b << ' ' << y.a << ' ' << y.b << endl;
return make_pair(x, y);
} void work(Point *pt) {
Line a = Line(pt[], pt[]);
Line b = Line(pt[], pt[]);
if (parallel(a, b)) {
if (onSeg(pt[], b) || onSeg(pt[], b)) { puts("0 1"); return ;}
if (onSeg(pt[], a) || onSeg(pt[], a)) { puts("0 1"); return ;}
// cout << "parallel" << endl;
Rat tmp = min(min(pt2Seg(pt[], b), pt2Seg(pt[], b)), min(pt2Seg(pt[], a), pt2Seg(pt[], a)));
tmp.fix();
printf("%lld %lld\n", tmp.a, tmp.b);
return ;
}
Vec nor = crossDet(a.vec(), b.vec());
Rat ans = pt2Plane(pt[], pt[], nor);
// cout << "~~~" << endl;
if (ans == ) {
// cout << "same plane" << endl;
if (segIntersect(a, b)) { puts("0 1"); return ;}
Rat tmp = min(min(pt2Seg(pt[], b), pt2Seg(pt[], b)), min(pt2Seg(pt[], a), pt2Seg(pt[], a)));
tmp.fix();
printf("%lld %lld\n", tmp.a, tmp.b);
return ;
} else {
// cout << "diff plane" << endl;
pair<Rat, Rat> tmp = getIntersect(a, b);
// cout << tmp.first.val() << "= =" << tmp.second.val() << endl;
// cout << (tmp.first > 0) << endl;
if (tmp.first > && tmp.first < && tmp.second > && tmp.second < ) {
// cout << "cross" << endl;
ans.fix();
printf("%lld %lld\n", ans.a, ans.b);
} else {
// cout << "not cross" << endl;
Rat t = min(min(pt2Seg(pt[], b), pt2Seg(pt[], b)), min(pt2Seg(pt[], a), pt2Seg(pt[], a)));
t.fix();
printf("%lld %lld\n", t.a, t.b);
}
}
} int main() {
// freopen("in", "r", stdin);
// freopen("out", "w", stdout);
Point pt[];
int T;
cin >> T;
while (T--) {
for (int i = ; i < ; i++) {
for (int j = ; j < ; j++) {
scanf("%lld", &pt[i].x[j]);
}
}
work(pt);
}
return ;
} /*
13 -20 -20 -20 20 20 19
0 0 0 1 1 1 -20 -20 -20 20 19 20
-20 -20 20 20 20 -20 0 0 0 20 20 20
0 0 10 0 20 10 0 0 0 1 1 1
2 3 4 1 2 2 0 0 0 0 0 0
0 1 1 1 2 3 0 0 0 10 10 10
11 12 13 10 11 11 0 0 0 1 1 1
1 1 1 2 2 2 1 0 0 0 1 0
1 1 0 2 2 0 1 0 0 0 1 0
0 0 0 1 1 0 0 0 0 0 0 20
20 0 10 0 20 10 0 0 0 20 20 20
1 1 2 1 1 2 0 0 0 20 20 20
0 20 20 0 20 20 0 0 0 0 0 20
20 20 0 20 20 20
*/
——written by Lyon
LA 4973 Ardenia (3D Geometry + Simulation)的更多相关文章
- uvalive 4973 Ardenia
题意:给出空间两条线段,求距离. 注意输出格式! #include<cstdio> #include<cmath> #include<algorithm> usin ...
- LA 4973异面线段
题目大意:给两条线段求他们间的最小距离的平方(以分数形式输出). 贴个模版吧!太抽象了. #include<cstdio> #include<cmath> #include&l ...
- .Uva&LA部分题目代码
1.LA 5694 Adding New Machine 关键词:数据结构,线段树,扫描线(FIFO) #include <algorithm> #include <cstdio&g ...
- Pushing state-of-the-art in 3D content understanding
Pushing state-of-the-art in 3D content understanding 2019-10-31 06:34:08 This blog is copied from: h ...
- LA 4064 Magnetic Train Tracks
题意:给定平面上$n(3\leq n \leq 1200)$个无三点共线的点,问这些点组成了多少个锐角三角形. 分析:显然任意三点可构成三角形,而锐角三角形不如直角或钝角三角形容易计数,因为后者有且仅 ...
- LA 4998 Simple Encryption
题意:输入正整数$K_1(K_1 \leq 50000)$, 找一个$12$位正整数$K_2$(不能含有前导零)使得${K_1}^{K_2}\equiv K_2(mod10^{12})$. 例如,$K ...
- LA 3704 Cellular Automaton
题意概述: 等价地,本题可以转化为下面的问题: 考虑$n \times n$的$0-1$矩阵$A$,在第$i$行上第$[-d+i, d+i]$(模$n$意义下)列对应的元素为$1$,其余为$0$.求$ ...
- 计算机视觉code与软件
Research Code A rational methodology for lossy compression - REWIC is a software-based implementatio ...
- [OSG]OSG的相关扩展
参考:osg官网 http://www.osgchina.org/index.php?view=article&id=176 http://trac.openscenegraph.org/pr ...
随机推荐
- linux性能监视工具sar
sar是一个优秀的一般性能监视工具,它可以输出Linux所完成的几乎所有工作的数据.sar命令在sysetat rpm中提供.示例中使用sysstat版本5.0.5,这是稳定的最新版本之一.关于版本和 ...
- 洛谷P2426 删数 [2017年4月计划 动态规划12]
P2426 删数 题目描述 有N个不同的正整数数x1, x2, ... xN 排成一排,我们可以从左边或右边去掉连续的i(1≤i≤n)个数(只能从两边删除数),剩下N-i个数,再把剩下的数按以上操作处 ...
- CSS实现火焰效果
代码如下 //主要就是用css动画实现的 <!DOCTYPE html> <html lang="en"> <head> <meta ch ...
- 函数的length属性
函数的length 属性指明函数的形参个数. length 是函数对象的一个属性值,指该函数有多少个必须要传入的参数,即形参的个数.形参的数量不包括剩余参数个数,仅包括第一个具有默认值之前的 ...
- python实现六大分群质量评估指标(兰德系数、互信息、轮廓系数)
python实现六大分群质量评估指标(兰德系数.互信息.轮廓系数) 1 R语言中的分群质量--轮廓系数 因为先前惯用R语言,那么来看看R语言中的分群质量评估,节选自笔记︱多种常见聚类模型以及分群质量评 ...
- 【JZOJ5088】【GDOI2017第四轮模拟day2】最小边权和 排序+动态规划
题面 有一张n个点m条边的有向图,每条边有一个互不相同的边权w,有q个询问,要求你从点a经过不超过c条边到点b,要求经过的边权递增并和尽量小,求出最小的边权和,如果没有合法方案则输出-1. 对于100 ...
- ORACLE 最后表数据更新的时间
SELECT SCN_TO_TIMESTAMP(MAX(ora_rowscn)) from myTable;
- 【JZOJ3873】【NOIP2014八校联考第4场第2试10.20】乐曲创作(music)
ujfuiaty 小可可是音乐学院的一名学生,他需要经常创作乐曲完成老师布置的作业. 可是,小可可是一个懒惰的学生.所以,每次完成作业时,他不会重新创作一首新的乐曲,而是去修改上一次创作过的乐曲作为作 ...
- web框架起源
web框架 python三大主流web框架 django 大而全,自带的组件和功能极多, 缺点:写小项目时候会比较笨重(杀鸡用牛刀),大并发不行,3000撑死 flask 小而精 自带的组件和功能极少 ...
- Directx11教程(15) D3D11管线(4)
原文:Directx11教程(15) D3D11管线(4) 本章我们首先了解一下D3D11中的逻辑管线,认识一下管线中每个stage的含义. 参考资料:http://fgiesen.wordpress ...