海倫公式を用いた3次元空間内の最大三角形面積の計算

牛客网の問題を基にした解答です。

3次元空間内にN個の点が存在し、各点は赤(R)、緑(G)、青(B)のいずれかの色を持ちます。最大面積をもつ三角形を形成する3点を選び、その面積を計算します。ただし、三角形の3点の色は以下の条件を満たす必要があります。

3点の色が全て同じ場合 3点の色が全て異なる場合

入力形式:
最初に正整数Nを入力します。Nは3次元空間内に存在する点の数です。(N <= 50)<br>
次にN行の点の情報を入力します。各点の情報は c x y z という形式で、cは色(R/G/B)、x,y,zは整数座標です。
出力形式:
最大面積を計算し、5小数点以下で出力します。

例入力

5
R 0 0 0
R 0 4 0
R 0 0 3
G 92 14 7
G 12 16 8

出力

6.00000

海倫公式について:

三角形の3辺の長さをa, b, cとし、半周長pを以下のように定義します。 p = (a + b + c) / 2 面積Sを以下のように計算します。 S = sqrt[p * (p - a) * (p - b) * (p - c)]

以下にJavaでの実装例を示します。

import java.util.*;

public class GeometryCalculator {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);

        int numberOfPoints = scanner.nextInt();

        int[] xCoordinates = new int[numberOfPoints];
        int[] yCoordinates = new int[numberOfPoints];
        int[] zCoordinates = new int[numberOfPoints];
        char[] colors = new char[numberOfPoints];

        for (int i = 0; i < numberOfPoints; i++) {
            String color = scanner.next();
            xCoordinates[i] = scanner.nextInt();
            yCoordinates[i] = scanner.nextInt();
            zCoordinates[i] = scanner.nextInt();
            colors[i] = color.charAt(0);
        }

        double maximumArea = 0.0;

        for (int i = 0; i < numberOfPoints; i++) {
            for (int j = 0; j < numberOfPoints; j++) {
                if (j == i) continue;

                for (int k = 0; k < numberOfPoints; k++) {
                    if (k == i || k == j) continue;

                    boolean sameColor = (colors[i] == colors[j] && colors[j] == colors[k]);
                    boolean allDifferent = (colors[i] != colors[j] && colors[i] != colors[k] && colors[j] != colors[k]);

                    if (sameColor || allDifferent) {
                        double area = calculateTriangleArea(
                            xCoordinates[i], yCoordinates[i], zCoordinates[i],
                            xCoordinates[j], yCoordinates[j], zCoordinates[j],
                            xCoordinates[k], yCoordinates[k], zCoordinates[k]);
                        if (area > maximumArea) {
                            maximumArea = area;
                        }
                    }
                }
            }
        }

        System.out.println(String.format("%.5f", maximumArea));
    }

    // 海倫公式を用いた三角形面積計算
    private static double calculateTriangleArea(
        int x1, int y1, int z1,
        int x2, int y2, int z2,
        int x3, int y3, int z3) {

        double sideA = Math.sqrt(
            Math.pow(x1 - x2, 2) + 
            Math.pow(y1 - y2, 2) + 
            Math.pow(z1 - z2, 2));

        double sideB = Math.sqrt(
            Math.pow(x2 - x3, 2) + 
            Math.pow(y2 - y3, 2) + 
            Math.pow(z2 - z3, 2));

        double sideC = Math.sqrt(
            Math.pow(x1 - x3, 2) + 
            Math.pow(y1 - y3, 2) + 
            Math.pow(z1 - z3, 2));

        double semiPerimeter = (sideA + sideB + sideC) / 2.0;
        double area = Math.sqrt(
            semiPerimeter * 
            (semiPerimeter - sideA) * 
            (semiPerimeter - sideB) * 
            (semiPerimeter - sideC));

        return area;
    }
}

タグ: 海倫公式 3次元 面積最大化 Java

5月17日 22:56 投稿