結果
問題 | No.132 点と平面との距離 |
ユーザー | mamekin |
提出日時 | 2017-09-23 10:50:55 |
言語 | C++14 (gcc 12.3.0 + boost 1.83.0) |
結果 |
AC
|
実行時間 | 1,784 ms / 5,000 ms |
コード長 | 4,885 bytes |
コンパイル時間 | 1,057 ms |
コンパイル使用メモリ | 110,236 KB |
実行使用メモリ | 6,820 KB |
最終ジャッジ日時 | 2024-11-14 03:57:30 |
合計ジャッジ時間 | 4,029 ms |
ジャッジサーバーID (参考情報) |
judge1 / judge2 |
(要ログイン)
テストケース
テストケース表示入力 | 結果 | 実行時間 実行使用メモリ |
---|---|---|
testcase_00 | AC | 67 ms
6,820 KB |
testcase_01 | AC | 530 ms
6,816 KB |
testcase_02 | AC | 1,784 ms
6,816 KB |
ソースコード
#define _USE_MATH_DEFINES #include <cstdio> #include <iostream> #include <sstream> #include <fstream> #include <iomanip> #include <algorithm> #include <cmath> #include <complex> #include <string> #include <vector> #include <list> #include <queue> #include <stack> #include <set> #include <map> #include <bitset> #include <numeric> #include <limits> #include <climits> #include <cfloat> #include <functional> #include <iterator> using namespace std; template <class T1> class Operators { public: template <class T2> const T1 operator+(const T2& right) const{ T1 ans = static_cast<const T1&>( *this ); ans += right; return ans; } template <class T2> const T1 operator-(const T2& right) const{ T1 ans = static_cast<const T1&>( *this ); ans -= right; return ans; } template <class T2> const T1 operator*(const T2& right) const{ T1 ans = static_cast<const T1&>( *this ); ans *= right; return ans; } template <class T2> const T1 operator/(const T2& right) const{ T1 ans = static_cast<const T1&>( *this ); ans /= right; return ans; } bool operator!=(const T1& right) const{ const T1& left = static_cast<const T1&>( *this ); return !(left == right); } bool operator>(const T1& right) const{ const T1& left = static_cast<const T1&>( *this ); return right < left; } bool operator<=(const T1& right) const{ const T1& left = static_cast<const T1&>( *this ); return !(right < left); } bool operator>=(const T1& right) const{ const T1& left = static_cast<const T1&>( *this ); return !(left < right); } }; class Point : public Operators<Point> { public: double x, y, z; Point(){ x = y = z = 0.0; } Point(double x0, double y0, double z0){ x = x0; y = y0; z = z0; } Point& operator+=(const Point& p){ x += p.x; y += p.y; z += p.z; return *this; } Point& operator-=(const Point& p){ x -= p.x; y -= p.y; z -= p.z; return *this; } Point& operator*=(double a){ x *= a; y *= a; z *= a; return *this; } Point& operator/=(double a){ x /= a; y /= a; z /= a; return *this; } double length() const{ return sqrt(x * x + y * y + z * z); } double dist(const Point& p) const{ return sqrt(pow(x - p.x, 2) + pow(y - p.y, 2) + pow(z - p.z, 2)); } }; // 行列式を計算する double determinant(vector<vector<double> > mat) { const double EPS = 1.0e-10; const int n = mat.size(); double ret = 1.0; for(int i=0; i<n; ++i){ int tmp = i; for(int j=i+1; j<n; ++j){ if(abs(mat[j][i]) > abs(mat[tmp][i])) tmp = j; } if(abs(mat[tmp][i]) < EPS) return 0.0; if(tmp != i){ mat[i].swap(mat[tmp]); ret *= -1.0; } for(int j=i+1; j<n; ++j){ for(int k=n-1; k>=i; --k){ mat[j][k] -= mat[i][k] * (mat[j][i] / mat[i][i]); } } ret *= mat[i][i]; } return ret; } /***************************************************************************************************/ // 三角形の面積を求める(ヘロンの公式) // a, b, c : 3辺の長さ /***************************************************************************************************/ double triangleArea(double a, double b, double c) { double s = (a + b + c) / 2.0; return sqrt(s * (s - a) * (s - b) * (s - c)); } /***************************************************************************************************/ // 四面体の体積を求める // x, y, z : 4つの頂点の座標 /***************************************************************************************************/ double tetrahedronVolume(const vector<Point>& p) { vector<vector<double> > mat(4, vector<double>(4, 1.0)); for(int i=0; i<4; ++i){ mat[i][0] = p[i].x; mat[i][1] = p[i].y; mat[i][2] = p[i].z; } return abs(determinant(mat)) / 6.0; } int main() { int n; Point p; cin >> n >> p.x >> p.y >> p.z; vector<Point> q(n); for(int i=0; i<n; ++i) cin >> q[i].x >> q[i].y >> q[i].z; double ans = 0.0; for(int i=0; i<n; ++i){ for(int j=0; j<i; ++j){ for(int k=0; k<j; ++k){ vector<Point> a = {q[i], q[j], q[k], p}; double volume = tetrahedronVolume(a); double area = triangleArea(q[i].dist(q[j]), q[j].dist(q[k]), q[k].dist(q[i])); ans += volume / area * 3.0; } } } printf("%.10f\n", ans); return 0; }