#include using namespace std; #define FOR(i,a,b) for(int i=(a);i<(b);++i) #define REP(i,n) FOR(i,0,n) #define ALL(v) begin(v),end(v) template inline bool chmax(A & a, const B & b) { if (a < b) { a = b; return true; } return false; } template inline bool chmin(A & a, const B & b) { if (a > b) { a = b; return true; } return false; } using ll = long long; using pii = pair; constexpr ll INF = 1ll<<30; constexpr ll longINF = 1ll<<60; constexpr ll MOD = 1000000007; constexpr bool debug = false; //---------------------------------// #include #include #include template struct Vec { using value_type = T; using const_reference = const value_type &; constexpr static value_type eps = 1e-8; private: value_type x, y, z; constexpr static value_type zero_limit = 1e-100; public: constexpr Vec() : x(0), y(0), z(0) {} constexpr Vec(const_reference x, const_reference y, const_reference z) : x(zero_round(x)), y(zero_round(y)), z(zero_round(z)) {} constexpr Vec operator +() const noexcept { return *this; } constexpr Vec operator -() const noexcept { return {-x, -y, -z}; } constexpr Vec & operator +=(const Vec & rhs) noexcept { x += rhs.x; y += rhs.y; z += rhs.z; return *this; } constexpr Vec & operator -=(const Vec & rhs) noexcept { x -= rhs.x; y -= rhs.y; z -= rhs.z; return *this; } constexpr Vec & operator *=(const_reference rhs) noexcept { x *= rhs; y *= rhs; z *= rhs; return *this; } constexpr Vec & operator /=(const_reference rhs) noexcept { assert(zero_round(rhs) != 0); x /= rhs; y /= rhs; z /= rhs; return *this; } friend constexpr Vec operator +(const Vec & lhs, const Vec & rhs) noexcept { return Vec(lhs) += rhs; } friend constexpr Vec operator -(const Vec & lhs, const Vec & rhs) noexcept { return Vec(lhs) -= rhs; } friend constexpr Vec operator *(const Vec & lhs, const_reference rhs) noexcept { return Vec(lhs) *= rhs; } friend constexpr Vec operator /(const Vec & lhs, const_reference rhs) noexcept { return Vec(lhs) /= rhs; } friend constexpr Vec operator *(const_reference lhs, const Vec & rhs) noexcept { return Vec(rhs) *= lhs; } friend constexpr Vec operator /(const_reference lhs, const Vec & rhs) noexcept { return Vec(rhs) /= lhs; } friend constexpr bool operator ==(const Vec & lhs, const Vec & rhs) noexcept { return !sign(lhs.x, rhs.x) && !sign(lhs.y, rhs.y) && !sign(lhs.z, rhs.z); } friend constexpr bool operator !=(const Vec & lhs, const Vec & rhs) noexcept { return !(lhs == rhs); } constexpr value_type dot(const Vec & rhs) const noexcept { return x * rhs.x + y * rhs.y + z * rhs.z; } constexpr Vec cross(const Vec & rhs) const noexcept { return {y * rhs.z - z * rhs.y, z * rhs.x - x * rhs.z, x * rhs.y - y * rhs.x}; } friend constexpr value_type dot(const Vec & lhs, const Vec & rhs) noexcept { return lhs.dot(rhs); } friend constexpr Vec cross(const Vec & lhs, const Vec & rhs) noexcept { return lhs.cross(rhs); } constexpr value_type norm2() const noexcept { return std::sqrt(square()); } constexpr value_type square() const noexcept { return dot(*this); } constexpr void normalize() noexcept { *this /= norm2(); } constexpr Vec normalized() const noexcept { return Vec(*this) /= norm2(); } std::tuple val() const noexcept { return {x, y, z}; } const_reference getx() const noexcept { return x; } const_reference gety() const noexcept { return y; } const_reference getz() const noexcept { return z; } constexpr static value_type zero_round(const value_type & r) noexcept { return std::abs(r) < zero_limit ? 0 : r; } constexpr static int sign(const value_type & r) noexcept { return (r > eps) - (r < -eps); } constexpr static int sign(const value_type & lhs, const value_type &rhs) noexcept { return sign(lhs - rhs); } }; int main() { Vec p[4]; REP(i, 4) { int x, y, z; scanf("%d %d %d", &x, &y, &z); p[i] = Vec(x, y, z); } auto n = cross(p[1] - p[0], p[2] - p[0]).normalized(); const double t = dot(p[0] - p[3], n); const auto tar = p[3] + t * n; bool ans = true; REP(i, 3) { auto cur = cross(p[i] - tar, p[(i + 1) % 3] - tar).normalized(); ans &= cur == n; } puts(ans ? "YES" : "NO"); }