백준 문제풀이

[백준 2108번 문제] 통계학

eunda_coding 2022. 8. 7. 18:59

이 문제는 숫자들을 입력받아서 산술평균, 중앙값, 최빈값, 범위를 출력하는 문제이다.

산술평균, 중앙값과 범위를 구하는 것은 쉬웠는데 최빈값을 구하는게 가장 어려웠다.

다른 것은 금방 풀었는데 최빈값 푸는데 시간이 가장 오래 걸린 것 같다.

 

시간을 단축하기 위해서 sys.stdin.readline을 요즘 자주 사용하고 있다. 은근 꿀팁!

input = sys.stdin.readline

먼저 입력한 값 만큼 숫자를 입력받아서 빈 리스트에 저장해준다.

n = int(input())

num = []
for i in range(n):
    num.append(int(input()))
num.sort()

for문을 통해서 빈 리스트에 값들을 저장하고 sort함수를 통해 오름차순으로 저장을 하였다.

 

1. 산술평균

sum 함수를 이용해서 리스트 안에 값들을 더한 후 리스트 길이 만큼 나누어주면 평균을 구할 수 있다.

소수점 이하 첫째 자리에서 반올림한 값을 출력한다라는 조건이 있어서 round함수를 사용해서 반올림해주었다.

print(round(sum(num)/n))

2. 중앙값

중앙값은 num리스트의 인덱스 값에 접근해서 구해 주었는데 리스트 길이를 반으로 나눈 후 올림을 해준 후 리스트는 0부터 시작하기 때문에 1을 빼주었다.

print(num[math.ceil(n/2)-1])

3. 최빈값

from collections import Counter 라는 외부 라이브러리를 사용해서 풀 수 있었다.
Counter(num).most_common(2) --> 는 num 리스트안에 있는 요소들이 몇 번 씩 나오는지 카운트해서 알려준다.

 print(cnt) 를 해주면 [(-2, 1), (1, 1)] 이런식으로 결과값이 나온다. most_common(2)사이에 2를 넣어주었기 때문에 리스트 앞에서 2번째 숫자까지의 카운트를 프린트해준다.

 

그래서 num 리스트에 2개 이상의 숫자가 있는경우에 빈도수가 같은경우에는 두번째로 작은 숫자를 출력하라고 한 조건이 있기 때문에 cnt[1][0]를 프린트해주고 그 외의 경우에는 빈도수가 가장 많은 정수를 프린트해주도록 하였다.

cnt = Counter(num).most_common(2)

if len(num) > 1:
    if cnt[0][1] == cnt[1][1]:
        print(cnt[1][0])
    else:
        print(cnt[0][0])
else:
    print(cnt[0][0])

4. 범위

범위는 리스트 내 가장 큰 값에서 가장 작은 수를 빼주면 나오는 값이다.

max와 min함수를 이용해서 풀었다.

print(max(num)-min(num))

<전체코드>

import sys
import math
from collections import Counter

input = sys.stdin.readline

n = int(input())

num = []
for i in range(n):
    num.append(int(input()))
# print("원래입력값", num)
num.sort()
# print("정렬된", num)

#산술평균
print(round(sum(num)/n))

#중앙값
print(num[math.ceil(n/2)-1])

#최빈값
cnt = Counter(num).most_common(2)

if len(num) > 1:
    if cnt[0][1] == cnt[1][1]:
        print(cnt[1][0])
    else:
        print(cnt[0][0])
else:
    print(cnt[0][0])

#범위
print(max(num)-min(num))