Where who wants to meet someone

백준 Swift [2108] 통계학 본문

백준 알고리즘 문제 기록/심화 2

백준 Swift [2108] 통계학

Lust3r 2023. 9. 12. 12:17
728x90

난이도

실버 III

 

문제

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

 

2108번: 통계학

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

www.acmicpc.net

 

내 답안

import Foundation

var numbers = [Int]()

let n = Int(readLine()!)!
var nDic = [Int : Int]()

for _ in 1...n {
    let inputValue = Int(readLine()!)!

    numbers.append(inputValue)

    let nCount = nDic[inputValue] ?? 0

    nDic.updateValue(nCount + 1, forKey: inputValue)
}

numbers.sort()

print(Int(round(Double(numbers.reduce(0, +)) / Double(n))))
print(numbers[n / 2])

let maxValue = nDic.max { $0.value < $1.value }?.value
let filteredNDic = nDic.filter { $0.value == maxValue }.keys.sorted()
filteredNDic.count == 1 ? print(filteredNDic[0]) : print(filteredNDic[1])

print(numbers[n - 1] - numbers[0])
  • 처음에는 산술평균, 중앙값, 범위 때문에라도 배열로 풀어야 한다 생각하고 틀을 짰는데 최빈값을 구하려면 dictionary가 필요했다.
  • 1. for문을 돌며 inputValue를 numbers와 nDic에 추가
  • 2. 중앙값과 범위를 위해 numbers 정렬
  • 3. 산술평균은 numbers를 reduce로 다 더한 값을 n으로 나누는데, round로 반올림을 하지 않으면 원하는 값이 나오지 않는다(소수점이 버려져서)
  • 4. 중앙값은 정렬된 numbers의 n / 2 인덱스 값. 중앙이 되려면 n / 2 + 1인데, 인덱스는 -1을 해줘야 하기 때문에 n / 2
  • 5-1. nDic의 max로 value가 가장 큰 값의 키-값 쌍을 구하고 그것의 value를 뽑아 maxValue에 담는다.
    5-2. nDic에서 value가 maxValue와 같은 항목을 filter하고, 그것의 key값만 뽑아 정렬(여러 값이 있을 경우 두 번째로 작은 값을 출력해야 해서)
    5-3.  filteredNDic에 1개만 있다면 그것을 출력하고, 아니라면(여러 값이 있다면) 두 번째 값인 인덱스 1의 값을 출력
  • 6. 범위는 최댓값과 최솟값의 차이이므로 numbers의 마지막 인덱스 값과 첫 인덱스 값을 빼주면 구할 수 있다.