https://www.acmicpc.net/problem/2166
다각형의 넓이 공식(aka 신발끈 공식)을 알면 손쉽게 구할 수 있는 문제이다.
문제의 입력을 보면
다각형을 이루는 순서대로 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
int
나 long
을 float
로 혹은 long
을 double
로 형 변환 시 정밀도가 손실될 수 있고, 이 경우 정수형으로 반올림될 수 있다고 한다.
이 경우 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)
}
Why does Java implicitly (without cast) convert a long
to a float
?