結果

問題 No.132 点と平面との距離
ユーザー ゴリポン先生
提出日時 2025-09-30 22:28:36
言語 D
(dmd 2.109.1)
結果
AC  
実行時間 250 ms / 5,000 ms
コード長 2,287 bytes
コンパイル時間 7,420 ms
コンパイル使用メモリ 212,892 KB
実行使用メモリ 7,716 KB
最終ジャッジ日時 2025-09-30 22:28:45
合計ジャッジ時間 7,721 ms
ジャッジサーバーID
(参考情報)
judge3 / judge5
このコードへのチャレンジ
(要ログイン)
ファイルパターン 結果
other AC * 3
権限があれば一括ダウンロードができます

ソースコード

diff #

module main;
// https://manabitimes.jp/math/679 より
// https://www.kashi-math.com/5602/ より
import std;

// 3次元ベクトル(double版)
struct Point3 {
	double x, y, z;
	// コンストラクタ
	this(double x, double y, double z)
	{
		this.x = x;
		this.y = y;
		this.z = z;
	}
	this(Point3 p)
	{
		x = p.x;
		y = p.y;
		z = p.z;
	}
	// 二項演算子
	Point3 opBinary(string op)(Point3 rhs) const
		if (op == "+" || op == "-")
	{
		mixin("return Point3(x " ~ op ~ " rhs.x, y " ~ op ~ " rhs.y, z " ~ op ~ " rhs.z);");
	}
	Point3 opBinary(string op, T)(T rhs) const
		if (isFloatingPoint!T && (op == "*" || op == "/"))
	{
		static if (op == "/")
			assert(rhs != 0);
		mixin("return Point3(x " ~ op ~ " rhs, y " ~ op ~ " rhs, z " ~ op ~ " rhs);");
	}
	Point3 opBinaryRight(string op, T)(T lhs) const
		if (isFloatingPoint!T && op == "*")
	{
		return rhs * lhs;
	}
	// 単項演算子
	Point3 opUnary(op)() const
		if (op == "+" || op == "-")
	{
		mixin("return Point3(" ~ op ~ "x, " ~ op ~ "y, " ~ op ~ "z);");
	}
	// 比較演算子
	double opCmp(Point3 rhs) const
	{
		if (sgn(x - rhs.x)) return sgn(x - rhs.x);
		if (sgn(y - rhs.y)) return sgn(y - rhs.y);
		return sgn(z - rhs.z);
	}
	// ノルム
	double norm() const
	{
		return x * x + y * y + z * z;
	}
	// 絶対値
	double abs() const
	{
		return sqrt(norm());
	}
	// 外積
	Point3 det(Point3 rhs) const
	{
		return Point3(y * rhs.z - z * rhs.y, z * rhs.x - x * rhs.z, x * rhs.y - y * rhs.x);
	}
	// 内積
	double dot(Point3 rhs) const
	{
		return x * rhs.x + y * rhs.y + z * rhs.z;
	}
	string toString() const
	{
		return format("(%f, %f, %f)", x, y, z);
	}
}
Point3 P;
// 点Pと平面abcの距離を求める
double dist(Point3 a, Point3 b, Point3 c)
{
	auto ab = b - a, ac = c - a;
	// 平面の法線ベクトル
	auto n = ab.det(ac);
	return abs((a - P).dot(n)) / n.abs();
}

void main()
{
	// 入力
	int N = readln.chomp.to!int;
	readln.chomp.formattedRead("%f %f %f", P.x, P.y, P.z);
	auto Q = new Point3[](N);
	foreach (ref q; Q)
		readln.chomp.formattedRead("%f %f %f", q.x, q.y, q.z);
	// 答えの計算
	double ans = 0;
	foreach (i; 0 .. N - 2) {
		foreach (j; i + 1 .. N - 1) {
			foreach (k; j + 1 .. N) {
				ans += dist(Q[i], Q[j], Q[k]);
			}
		}
	}
	// 答えの出力
	writefln("%.12f", ans);
}
0