1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107
| #include <iostream>
namespace __3dvector { using i64 = long long; struct Vec { i64 x, y, z; Vec(i64 _x = 0, i64 _y = 0, i64 _z = 0): x(_x), y(_y), z(_z) {} }; Vec zero(0, 0, 0); bool operator==(const Vec& v1, const Vec& v2) { return v1.x == v2.x && v1.y == v2.y && v1.z == v2.z; } bool operator!=(const Vec& v1, const Vec& v2) { return v1.x != v2.x || v1.y != v2.y || v1.z != v2.z; } Vec operator+(const Vec& v1, const Vec& v2) { return Vec(v1.x + v2.x, v1.y + v2.y, v1.z + v2.z); } i64 dot(const Vec& v1, const Vec& v2) { return v1.x * v2.x + v1.y * v2.y + v1.z * v2.z; } Vec cross(const Vec& v1, const Vec& v2) { return Vec( v1.y * v2.z - v1.z * v2.y, - v1.x * v2.z + v1.z * v2.x, v1.x * v2.y - v1.y * v2.x ); } }
using namespace __3dvector;
inline int sgn(i64 x) { return (x > 0) - (x < 0); }
bool judge(const Vec& v1, const Vec& v2) { return sgn(v1.x) * sgn(v2.x) >= 0 && sgn(v1.y) * sgn(v2.y) >= 0 && sgn(v1.z) * sgn(v2.z) >= 0; }
void solve() { Vec v[4]; for (int i = 0; i < 4; i++) std::cin >> v[i].x >> v[i].y >> v[i].z; i64 x1 = v[0].x, x2 = v[1].x, x3 = v[2].x; i64 y1 = v[0].y, y2 = v[1].y, y3 = v[2].y; i64 z1 = v[0].z, z2 = v[1].z, z3 = v[2].z; i64 det = x1 * y2 * z3 + x2 * y3 * z1 + x3 * y1 * z2 - x3 * y2 * z1 - x2 * y1 * z3 - x1 * y3 * z2; if (det) { Vec cr1 = cross(v[0], v[1]), cr2 = cross(v[1], v[2]), cr3 = cross(v[2], v[0]); Vec vt = v[0] + v[1] + v[2]; i64 dt1 = dot(vt, cr1); i64 d1 = dot(v[3], cr1), d2 = dot(v[3], cr2), d3 = dot(v[3], cr3); if (sgn(d1) * sgn(dt1) >= 0 && sgn(d2) * sgn(dt1) >= 0 && sgn(d3) * sgn(dt1) >= 0) { std::cout << "YES\n"; return; } } else { for (int i = 0; i < 3; i++) { for (int j = i + 1; j < 3; j++) { Vec cr = cross(v[i], v[j]); if (cr == zero) { if (cross(v[3], v[i]) == zero && cross(v[3], v[j]) == zero && (v[i] != zero && judge(v[3], v[i]) || v[j] != zero && judge(v[3], v[j]))) { std::cout << "YES\n"; return; } else if (v[i] == zero && v[j] == zero) { if (v[3] == zero) { std::cout << "YES\n"; return; } } } else { if (dot(v[3], cr) == 0) { Vec cri = cross(v[3], v[i]), crj = cross(v[3], v[j]); Vec vt = v[i] + v[j]; Vec crit = cross(vt, v[i]), crjt = cross(vt, v[j]); if (judge(cri, crit) && judge(crj, crjt)) { std::cout << "YES\n"; return; } } } } } }
std::cout << "NO\n"; }
int main() { std::ios::sync_with_stdio(false); std::cin.tie(nullptr); std::cout.tie(nullptr);
int numTest; std::cin >> numTest; while (numTest--) solve();
return 0; }
|