아임'준
[BOJ / 파이썬] 2108: 통계학 본문
백준 / BOJ / Python / 파이썬
문제 링크 : https://www.acmicpc.net/problem/2108
단계 : 정렬
알고리즘 분류 : 구현, 정렬
풀이:
주어진 n개의 숫자들을 ls라는 리스트에 저장한다.
산술평균은 ls의 전체 합 / n을 round 함수를 통해 소수점 이하 첫째 자리에서 반올림하여 구할 수 있다.
중앙값의 경우 ls를 정렬해주고 n을 2로 나누었을 때의 몫을 이용하여 구할 수 있다.
최빈값이 조금 복잡한데 collections의 Counter를 이용할 것이다. Counter.most_common()을 통해 각 원소당 나온 횟수를 구할 수 있는데 이때 이를 기준으로 정렬이 되어 temp에 저장된다. 그리고 최빈값이 여러개일 경우를 대비하여 temp의 첫번째 값이 나온 횟수(temp[0][1])를 두번째 값이 나온 횟수(temp[1][1])와 비교하여 같다면 두번째 값(temp[1][0])을 출력한다. 둘이 나온 횟수가 같지 않다면 최빈값이 하나이므로 첫번째 값(temp[0][0])을 출력한다. 또한 같은 숫자가 한개만 여러번 주어졌을 수 있는데 이때 temp의 길이는 1일 것이므로 이럴 경우 바로 temp[0][0]을 출력한다.
최빈값을 구하는 또 다른 방법은 sorted 함수를 이용하는 것이다. temp에 sorted를 이용하여 ls.count를 기준(key = ls.count)으로 내림차순(reverse = True) 정렬을 한 후 set로 바꾸어주어 중복된 값들을 제거해주면 최빈값을 작은 값부터 구할 수 있다. 이는 파이썬이 정렬을 할 때 최대한 원래 형태를 유지하려는 성질이 있어서인데 ls가 이미 위에서 ls.sort로 작은수부터 정렬이 돼 있기 때문에 ls.count를 기준으로 정렬했을 때 같은 횟수로 등장한 숫자가 있다면 기존 정렬된 작은 숫자를 앞으로 두기 때문이다. 그렇게 ls 리스트에서 temp[0]이 등장한 횟수와 temp[1]이 등장한 횟수가 같다면 temp[1]을 아니라면 temp[0]을 출력해준다.
범위는 정렬된 ls를 마지막 값에서 첫번째 값을 뺌을 통해 구할 수 있다.
코드
import sys
from collections import Counter
n = int(sys.stdin.readline())
ls = []
for i in range(n):
ls.append(int(sys.stdin.readline()))
ls.sort()
print(int(round(sum(ls) / n, 0))) # 산술평균
print(ls[n // 2]) # 중앙값
temp = Counter(ls).most_common()
if len(temp) > 1:
if temp[0][1] == temp[1][1]:
print(temp[1][0]) # 최빈값이 여러개이면 두번째로 작은 것
else:
print(temp[0][0]) # 최빈값이 하나일 때
else:
print(temp[0][0]) # unique한 값이 하나였을 때
print(ls[-1] - ls[0]) # 범위
#최빈값 구하는 두번째 코드
temp = sorted(ls, key=ls.count, reverse=True)
temp = list(set(temp))
if ls.count(temp[0]) == ls.count(temp[1]):
print(temp[1]) # 최빈값
else:
print(temp[0])
'문제풀이 > BOJ' 카테고리의 다른 글
[BOJ / 파이썬] 11650: 좌표 정렬하기 (0) | 2021.10.06 |
---|---|
[BOJ / 파이썬] 1427: 소트인사이드 (0) | 2021.10.06 |
[BOJ / 파이썬] 10989: 수 정렬하기 3 (0) | 2021.10.05 |
[BOJ / 파이썬] 2751: 수 정렬하기 2 (0) | 2021.10.04 |
[BOJ / 파이썬] 11729: 하노이 탑 이동 순서 (0) | 2021.10.04 |