본문 바로가기
  • 개발하는 곰돌이
Algorithm/BOJ

[Kotlin] 백준 2108 : 통계학

by 개발하는 곰돌이 2022. 12. 2.

문제 링크

 

2108번: 통계학

첫째 줄에 수의 개수 N(1 ≤ N ≤ 500,000)이 주어진다. 단, N은 홀수이다. 그 다음 N개의 줄에는 정수들이 주어진다. 입력되는 정수의 절댓값은 4,000을 넘지 않는다.

www.acmicpc.net



문제 해설

주어진 입력으로부터 제시된 값들을 구하면 된다. 1, 2, 4는 손쉽게 구할 수 있지만, 최빈값을 구하고 최빈값이 여러개일 때 두 번째로 작은 값을 구하는 부분은 조금 생각을 해봐야 한다.

 

최빈값을 구하기 위해 수가 나타나는 빈도를 저장할 별도의 배열을 생성한다. 그리고 N개의 수를 입력받으면서 빈도를 저장할 배열에서 입력하는 수 + 4000을 인덱스로 하는 요소값을 1씩 증가시킨다. N개의 수 입력이 끝났다면 빈도수를 저장한 배열의 최대값이 2개 이상인지 확인하여 가장 앞의 인덱스(=가장 작은 수)의 빈도를 1 감소시킨다.

 

최빈값을 구했다면 N개의 수를 입력받은 배열을 정렬하고 산술평균, 중앙값, 범위를 구하면 된다. 최빈값은 빈도를 저장한 배열의 최대값을 갖는 인덱스 - 4000을 출력하면 된다.


Code

import kotlin.math.roundToInt

fun main() = with(System.`in`.bufferedReader()) {
    val bw = System.out.bufferedWriter()
    val numbers = IntArray(readLine().toInt())
    val cnt = IntArray(8001)
    var n: Int
    for (i in numbers.indices) {
        numbers[i] = readLine().toInt().also { n = it }
        cnt[n + 4000]++
    }
    if (cnt.count { it == cnt.maxOrNull() } >= 2) cnt[cnt.indexOf(cnt.maxOrNull()!!)]--
    numbers.sort()
    bw.write("${(numbers.sum().toDouble() / numbers.size).roundToInt()}\n")	// 산술평균
    bw.write("${numbers[numbers.size / 2]}\n")	// 중앙값
    bw.write("${cnt.indexOf(cnt.maxOrNull()!!) - 4000}\n")	// 최빈값
    bw.write("${numbers.last() - numbers[0]}")	// 범위
    bw.close()
}

댓글