博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
LA 4973 Ardenia (3D Geometry + Simulation)
阅读量:6858 次
发布时间:2019-06-26

本文共 7239 字,大约阅读时间需要 24 分钟。

  三维几何,题意是要求求出两条空间线段的距离。题目难度在于要求用有理数的形式输出,这就要求写一个有理数类了。

  开始的时候写出来的有理数类就各种疯狂乱套,TLE的结果是显然的。后来发现,在计算距离前都是不用用到有理数类的,所以就将开始的部分有理数改成直接用long long。其实好像可以用int来做的,不过我的方法比较残暴,中间运算过程居然爆int了。所以就只好用long long了。

代码如下,附带debug以及各种强的数据:

1 #include 
2 #include
3 #include
4 #include
5 #include
6 7 using namespace std; 8 9 template
T gcd(T a, T b) { return b ? gcd(b, a % b) : a;} 10 template
T sqr(T x) { return x * x;} 11 typedef long long LL; 12 struct Rat { 13 LL a, b; 14 Rat() {} 15 Rat(LL x) { a = x, b = 1;} 16 Rat(LL _a, LL _b) { 17 LL GCD = gcd(_b, _a); 18 a = _a / GCD, b = _b / GCD; 19 } 20 double val() { return (double) a / b;} 21 bool operator < (Rat x) const { return a * x.b < b * x.a;} 22 bool operator > (Rat x) const { return a * x.b > b * x.a;} 23 bool operator == (Rat x) const { return a * x.b == b * x.a;} 24 bool operator < (LL x) const { return Rat(a, b) < Rat(x);} 25 bool operator > (LL x) const { return Rat(a, b) > Rat(x);} 26 bool operator == (LL x) const { return Rat(a, b) == Rat(x);} 27 Rat operator + (Rat x) { 28 LL tb = b * x.b, ta = a * x.b + b * x.a; 29 LL GCD = gcd(abs(tb), abs(ta)); 30 return Rat(ta / GCD, tb / GCD); 31 } 32 Rat operator - (Rat x) { 33 LL tb = b * x.b, ta = a * x.b - b * x.a; 34 LL GCD = gcd(abs(tb), abs(ta)); 35 return Rat(ta / GCD, tb / GCD); 36 } 37 Rat operator * (Rat x) { 38 if (a * x.a == 0) return Rat(0, 1); 39 // if (b * x.b == 0) { puts("..."); while (1) ;} 40 LL tb = b * x.b, ta = a * x.a; 41 LL GCD = gcd(abs(tb), abs(ta)); 42 return Rat(ta / GCD, tb / GCD); 43 } 44 Rat operator / (Rat x) { 45 if (a * x.b == 0) return Rat(0, 1); 46 // if (b * x.a == 0) { puts("!!!"); while (1) ;} 47 LL GCD, tb = b * x.a, ta = a * x.b; 48 GCD = gcd(abs(tb), abs(ta)); 49 return Rat(ta / GCD, tb / GCD); 50 } 51 void fix() { 52 a = abs(a), b = abs(b); 53 LL GCD = gcd(b, a); 54 a /= GCD, b /= GCD; 55 } 56 } ; 57 58 struct Point { 59 LL x[3]; 60 Point operator + (Point a) { 61 Point ret; 62 for (int i = 0; i < 3; i++) ret.x[i] = x[i] + a.x[i]; 63 return ret; 64 } 65 Point operator - (Point a) { 66 Point ret; 67 for (int i = 0; i < 3; i++) ret.x[i] = x[i] - a.x[i]; 68 return ret; 69 } 70 Point operator * (LL p) { 71 Point ret; 72 for (int i = 0; i < 3; i++) ret.x[i] = x[i] * p; 73 return ret; 74 } 75 bool operator == (Point a) const { 76 for (int i = 0; i < 3; i++) if (!(x[i] == a.x[i])) return false; 77 return true; 78 } 79 void print() { 80 for (int i = 0; i < 3; i++) cout << x[i] << ' '; 81 cout << endl; 82 } 83 } ; 84 typedef Point Vec; 85 86 struct Line { 87 Point s, t; 88 Line() {} 89 Line (Point s, Point t) : s(s), t(t) {} 90 Vec vec() { return t - s;} 91 } ; 92 typedef Line Seg; 93 94 LL dotDet(Vec a, Vec b) { 95 LL ret = 0; 96 for (int i = 0; i < 3; i++) ret = ret + a.x[i] * b.x[i]; 97 return ret; 98 } 99 100 Vec crossDet(Vec a, Vec b) {101 Vec ret;102 for (int i = 0; i < 3; i++) {103 ret.x[i] = a.x[(i + 1) % 3] * b.x[(i + 2) % 3] - a.x[(i + 2) % 3] * b.x[(i + 1) % 3];104 }105 return ret;106 }107 108 inline LL vecLen(Vec x) { return dotDet(x, x);}109 inline bool parallel(Line a, Line b) { return vecLen(crossDet(a.vec(), b.vec())) == 0;}110 inline bool onSeg(Point x, Point a, Point b) { return parallel(Line(a, x), Line(b, x)) && dotDet(a - x, b - x) < 0;}111 inline bool onSeg(Point x, Seg s) { return onSeg(x, s.s, s.t);}112 113 Rat pt2Seg(Point p, Point a, Point b) {114 if (a == b) return Rat(vecLen(p - a));115 Vec v1 = b - a, v2 = p - a, v3 = p - b;116 if (dotDet(v1, v2) < 0) return Rat(vecLen(v2));117 else if (dotDet(v1, v3) > 0) return Rat(vecLen(v3));118 else return Rat(vecLen(crossDet(v1, v2)), vecLen(v1));119 }120 inline Rat pt2Seg(Point p, Seg s) { return pt2Seg(p, s.s, s.t);}121 inline Rat pt2Plane(Point p, Point p0, Vec n) { return Rat(sqr(dotDet(p - p0, n)), vecLen(n));}122 inline bool segIntersect(Line a, Line b) {123 Vec v1 = crossDet(a.s - b.s, a.t - b.s);124 Vec v2 = crossDet(a.s - b.t, a.t - b.t);125 Vec v3 = crossDet(b.s - a.s, b.t - a.s);126 Vec v4 = crossDet(b.s - a.t, b.t - a.t);127 // v1.print();128 // v2.print();129 // cout << dotDet(v1, v2).val() << "= =" << endl;130 return dotDet(v1, v2) < 0 && dotDet(v3, v4) < 0;131 }// cout << "same plane" << endl;132 133 pair
getIntersect(Line a, Line b) {134 Point p = a.s, q = b.s;135 Vec v = a.vec(), u = b.vec();136 LL uv = dotDet(u, v), vv = dotDet(v, v), uu = dotDet(u, u);137 LL pv = dotDet(p, v), qv = dotDet(q, v), pu = dotDet(p, u), qu = dotDet(q, u);138 if (uv == 0) return make_pair(Rat(qv - pv, vv), Rat(pu - qu, uu));139 // if (vv == 0 || uv == 0 || uv / vv - uu / uv == 0) { puts("shit!"); while (1) ;}140 Rat y = (Rat(pv - qv, vv) - Rat(pu - qu, uv)) / (Rat(uv, vv) - Rat(uu, uv));141 Rat x = (y * uv - pv + qv) / vv;142 // cout << x.a << ' ' << x.b << ' ' << y.a << ' ' << y.b << endl;143 return make_pair(x, y);144 }145 146 void work(Point *pt) {147 Line a = Line(pt[0], pt[1]);148 Line b = Line(pt[2], pt[3]);149 if (parallel(a, b)) {150 if (onSeg(pt[0], b) || onSeg(pt[1], b)) { puts("0 1"); return ;}151 if (onSeg(pt[2], a) || onSeg(pt[3], a)) { puts("0 1"); return ;}152 // cout << "parallel" << endl;153 Rat tmp = min(min(pt2Seg(pt[0], b), pt2Seg(pt[1], b)), min(pt2Seg(pt[2], a), pt2Seg(pt[3], a)));154 tmp.fix();155 printf("%lld %lld\n", tmp.a, tmp.b);156 return ;157 }158 Vec nor = crossDet(a.vec(), b.vec());159 Rat ans = pt2Plane(pt[0], pt[2], nor);160 // cout << "~~~" << endl;161 if (ans == 0) {162 // cout << "same plane" << endl;163 if (segIntersect(a, b)) { puts("0 1"); return ;}164 Rat tmp = min(min(pt2Seg(pt[0], b), pt2Seg(pt[1], b)), min(pt2Seg(pt[2], a), pt2Seg(pt[3], a)));165 tmp.fix();166 printf("%lld %lld\n", tmp.a, tmp.b);167 return ;168 } else {169 // cout << "diff plane" << endl;170 pair
tmp = getIntersect(a, b);171 // cout << tmp.first.val() << "= =" << tmp.second.val() << endl;172 // cout << (tmp.first > 0) << endl;173 if (tmp.first > 0 && tmp.first < 1 && tmp.second > 0 && tmp.second < 1) {174 // cout << "cross" << endl;175 ans.fix();176 printf("%lld %lld\n", ans.a, ans.b);177 } else {178 // cout << "not cross" << endl;179 Rat t = min(min(pt2Seg(pt[0], b), pt2Seg(pt[1], b)), min(pt2Seg(pt[2], a), pt2Seg(pt[3], a)));180 t.fix();181 printf("%lld %lld\n", t.a, t.b);182 }183 }184 }185 186 int main() {187 // freopen("in", "r", stdin);188 // freopen("out", "w", stdout);189 Point pt[4];190 int T;191 cin >> T;192 while (T--) {193 for (int i = 0; i < 4; i++) {194 for (int j = 0; j < 3; j++) {195 scanf("%lld", &pt[i].x[j]);196 }197 }198 work(pt);199 }200 return 0;201 }202 203 /*204 13205 206 -20 -20 -20 20 20 19207 0 0 0 1 1 1208 209 -20 -20 -20 20 19 20210 -20 -20 20 20 20 -20211 212 0 0 0 20 20 20213 0 0 10 0 20 10214 215 0 0 0 1 1 1216 2 3 4 1 2 2217 218 0 0 0 0 0 0219 0 1 1 1 2 3220 221 0 0 0 10 10 10222 11 12 13 10 11 11223 224 0 0 0 1 1 1225 1 1 1 2 2 2226 227 1 0 0 0 1 0228 1 1 0 2 2 0229 230 1 0 0 0 1 0231 0 0 0 1 1 0232 233 0 0 0 0 0 20234 20 0 10 0 20 10235 236 0 0 0 20 20 20237 1 1 2 1 1 2238 239 0 0 0 20 20 20240 0 20 20 0 20 20241 242 0 0 0 0 0 20243 20 20 0 20 20 20244 */
View Code

 

——written by Lyon

 

转载于:https://www.cnblogs.com/LyonLys/p/LA_4973_Lyon.html

你可能感兴趣的文章
一段典型的PHP程序都包含那些内容呢?
查看>>
python paramiko模块讲解
查看>>
Windows Phone 7 数据绑定的简单介绍
查看>>
每天一个知识点linux(二)关机重启命令
查看>>
以程序的方式操纵NTFS的文件权限(下)
查看>>
LVM逻辑卷管理
查看>>
zabbix与nagios对比
查看>>
MySQL源码安装完成后修改安装路径启动问题
查看>>
合并下载的Solaris镜像为DVD文件的方法
查看>>
设计ShartPoint的组织结构和成员
查看>>
shell编程入门步步高(一、shell简介)
查看>>
一个简单的HQL优化
查看>>
从股价说起 百神大战凸现百度与腾讯阿里差距
查看>>
MariaDB六之主从复制
查看>>
outlook cannot send this item
查看>>
【Win7下Android native code的编译和调试】
查看>>
【iOS-cocos2d-X 游戏开发之十】自定义各类模版&触屏事件讲解!
查看>>
域环境下如何保护重要资料文件的安全(二)---IRM&RMS(下)
查看>>
服务器升迁架构.png
查看>>
不能联系xx域的域控制器
查看>>