牛客网の問題を基にした解答です。
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;
}
}