Today
Total
Recent Posts
Link
반응형
«   2025/05   »
1 2 3
4 5 6 7 8 9 10
11 12 13 14 15 16 17
18 19 20 21 22 23 24
25 26 27 28 29 30 31
Archives
관리 메뉴

아임'준

[BOJ / 파이썬] 2108: 통계학 본문

문제풀이/BOJ

[BOJ / 파이썬] 2108: 통계학

아임'준 2021. 10. 5. 12:14
반응형

백준 / 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])

Comments