[Python] BOJ/백준 2108번 통계학
[문제]
https://www.acmicpc.net/problem/2108
2108번: 통계학
첫째 줄에 수의 개수 N(1 ≤ N ≤ 500,000)이 주어진다. 단, N은 홀수이다. 그 다음 N개의 줄에는 정수들이 주어진다. 입력되는 정수의 절댓값은 4,000을 넘지 않는다.
www.acmicpc.net
[풀이]
산술평균, 중앙값, 범위 구하는 법은 쉬워서 패스.. 최빈값 구하는 게 아주 조금 까다로웠다.
처음에 입력 받을 때 sorted함수를 통해 차례대로 정렬한 상태로 리스트에 저장한다.
num_cnt 딕셔너리를 생성한 후 try-except문을 활용해 num_cnt에 숫자 당 빈도수를 저장했다.
for문으로 num에 있는 숫자를 차례대로 꺼내 num_cnt[i] += 1을 하게 되면
num_cnt[i]가 있을 경우에는 원래 있던 값에 1이 더해지고,
num_cnt[i]가 없었을 경우에는 except문을 통해 num_cnt[i]를 1로 초기화한다.
그 후 빈도수 값(딕셔너리의 value)만 모아 리스트를 만든 후 max() 함수를 통해 구한 가장 큰 수를 mode_num 변수에 담는다.
mode값을 담을 리스트를 생성한 후 num_cnt 딕셔너리를 차례대로 돌아 value값이 위에서 구한 mode_num과 일치할 경우 해당 key 값을 mode 리스트에 추가한다.
값을 차례대로 출력해주는데 만약 mode값이 1개일 경우에는 mode[0]을 출력하고, 2개 이상일 경우에는 두 번째로 작은 mode값인 mode[1]을 출력한다.
++ 근데 티스토리 기본모드는 인라인코드가 안되네 가독성 너무 떨어진다..
[코드]
import sys
if __name__ == '__main__':
num = sorted([int(sys.stdin.readline()) for _ in range(int(sys.stdin.readline()))])
average = round(sum(num) / len(num)) # 산술평균
median = num[(len(num) // 2)] # 중앙값
num_cnt = {} # key: 입력받은 숫자, value: 숫자 당 빈도수
for i in num:
try:
num_cnt[i] += 1
except:
num_cnt[i] = 1
mode_num = max(list(num_cnt.values())) # 딕셔너리의 value만 모아 리스트로 만든 후 그 중 최대값
mode = []
for i in num_cnt:
if num_cnt.get(i) == mode_num:
mode.append(i)
# 출력
print(average, median, sep='\n')
if len(mode) < 2:
print(mode[0])
else:
print(mode[1])
print(abs(num[-1]-num[0]))