結果
| 問題 |
No.132 点と平面との距離
|
| コンテスト | |
| ユーザー |
|
| 提出日時 | 2017-09-23 10:50:55 |
| 言語 | C++14 (gcc 13.3.0 + boost 1.87.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 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| other | AC * 3 |
ソースコード
#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;
}