[백준] 2216번: 다각형의 면적 - Kotlin

엄기훈·2024년 9월 23일
0

알고리즘 풀이

목록 보기
9/9
post-thumbnail

https://www.acmicpc.net/problem/2166

풀이

다각형의 넓이 공식(aka 신발끈 공식)을 알면 손쉽게 구할 수 있는 문제이다.

n차원 다각형의 넓이 계산

문제의 입력을 보면

다각형을 이루는 순서대로 N개의 점

이라는 문구가 있는데 이 조건이 없으면 문제를 풀기 쉽지 않다.

다각형의 넓이 공식 자체의 전제 조건이 좌표의 순서가 시계 방향이든, 반시계 방향이든 교차하지 않고 이어져야 넓이를 구할 수 있기 때문이다.

주의할 점

숫자형 변수 포매팅 문제

5
-100000 100000
-100000 -100000
100000 -100000
100000 99999
99999 100000

출력 : 3.9999999910E5
정답 : 39999999999.5

너무 큰 수를 코틀린에서 출력할 경우

4.0E10과 같이 지수 표기법으로 출력된다.

이를 위해서는 String.format 함수를 이용하여 원본 숫자 형태로 출력해야한다.

자료형 문제

5
-100000 100000
-100000 -100000
100000 -100000
100000 99999
99999 100000

예상값: 3.9999999910E5
실제값: 4.0E10

행렬식의 값을 더하는 변수를 Float와 Double로 했을 때 두 자료형에서의 값이 다르게 나온다. (Double의 경우가 맞는 결과였음)

Java Language Specification을 살펴보면

Conversion of an int or a long value to float, or of a long value to double, may result in loss of precision-that is, the result may lose some of the least significant bits of the value. In this case, the resulting floating-point value will be a correctly rounded version of the integer value

intlongfloat로 혹은 longdouble로 형 변환 시 정밀도가 손실될 수 있고, 이 경우 정수형으로 반올림될 수 있다고 한다.

이 경우 float보다는 double이 정밀도가 높아 올바르게 형변환이 이루어진 것 같다.

전체 코드

import kotlin.math.absoluteValue

fun main() {
    val N = readln().toInt()
    val dots = mutableListOf<Pair<Long, Long>>()
    repeat(N) {
        dots.add(readln().split(" ").map { it.toLong() }.let { Pair(it[0], it[1]) })
    }
    dots.add(dots[0])

    var area = 0.0
    for (i in 0 until N) {
        area += det(dots[i], dots[i + 1])
    }

    area = area.absoluteValue / 2
    println(String.format("%.1f", area))
}

fun det(aDot: Pair<Long, Long>, bDot: Pair<Long, Long>): Long {
    return (aDot.first * bDot.second) - (bDot.first * aDot.second)
}

참고 자료

n차원 다각형의 넓이 계산

Why does Java implicitly (without cast) convert a long to a float?

profile
한 번 더 고민해보는 개발자

0개의 댓글