Baekjoon 문제 풀기 (2108번 : 통계학) Python

2108번 : 통계학

1. 문제읽기


순서대로 구현하면 되는 문제

문제 자체를 이해하는데는 어렵지 않았다.
최빈값에서 살짝 걸렸는데, 가장 여러번 나오는 숫자라고 이해하면 된다.

2. 제출 코드


1, 2, 4번은 쉽게 풀 수 있었다.
3번을 풀긴 했는데 리스트를 엄청많이 쓰는 코드라 500,000 의 입력값을 받는 이 문제는 당연히 시간초과가 날 것 같았다.
다른 방법은 생각이 나지 않아 결국 포기했다.
찾아보니 counter함수를 사용해서 대부분 풀었다.
휴 다행이다. 계속 도전했으면 또 시간만 잡아먹었을 듯…
아래에서 counter 함수를 공부하고 나중에 다시 풀어봐야겠다.
아래는 시간초과 된 코드.. 2번 예제는 오류가 뜬다 ㅋㅋㅋ

import sys

n = int(sys.stdin.readline().rstrip())
arr = []
for _ in range(n):
	arr.append(int(sys.stdin.readline().rstrip()))

print(int(round(sum(arr)/n, 0)))
sorted_arr = sorted(arr)
mid_index = (len(arr)-1)//2
print(sorted_arr[mid_index])

set_arr = set(arr)
list_set_arr = list(set_arr)  # 중복 제거 리스트
num_arr = []  # count 한 값들의 리스트
for i in list_set_arr:
	num_arr.append(arr.count(i))

sorted_num_arr = []  # 동일 최빈값 리스트
if num_arr.count(max(num_arr)) == 1:
	print(list_set_arr.index(max(num_arr)))
else:
	for i in range(len(num_arr)):
		if num_arr[i] == max(num_arr):
			sorted_num_arr.append(i)

	tmp = []
	for i in sorted_num_arr:
		tmp.append(list_set_arr[i])
	tmp.sort()
	print(tmp[1])

print(max(arr)-min(arr))

3. 공부할 것


그냥 중복값을 찾는 문제였다면 예전에 풀었던 set을 이용하여 풀 수 있었을 것 같은데, 또 오름차순으로 나열하여 두번째로 작은 값을 찾아야해서 어려웠다.
counter 함수를 정리해보자.

Collections 모듈의 Counter 클래스

기본 자료구조인 사전(dictionary)를 확장하고 있는 클래스로 사전에서 제공하는 API를 그대로 사용 가능하다.
리스트나 문자열의 요소에 대한 개수를 구할 때 자주 사용한다.
최빈값을 구할 때 most_common 함수를 자주 사용한다.

most_common 메소드

collection.Counter(list).most_common(n) : 리스트에 담긴 튜플 형태로 반환
n을 명시하면 n개의 최빈값이 (타겟, 카운트) 순으로 출력된다.
명시하지 않으면 모두 출력된다.
또한 타겟은 자동적으로 오름차순으로 출력된다.

예제 코드
from collections import Counter
a = [-2, 1, 2, 3, 8]
print(Counter(a).most_common())
출력결과
[(-2, 1), (1, 1), (2, 1), (3, 1), (8, 1)]
정답 코드

most_common 메소드는 자동적으로 count하는 숫자를 오름차순으로 정렬 후 리스트에 담아주므로 앞에서 2개의 타겟 숫자가 일치하면 뒤쪽에 있는 타겟 숫자를 출력하면 된다.
예제 2번과 같이 1개의 숫자가 입력되는 경우를 대비하여 if문으로 count_arr의 길이가 1개일 때는 그냥 첫번째 타겟 숫자를 출력하게 한다.

from collections import Counter
import sys

n = int(sys.stdin.readline().rstrip())
arr = []
for _ in range(n):
	arr.append(int(sys.stdin.readline().rstrip()))

print(int(round(sum(arr)/n, 0)))
sorted_arr = sorted(arr)
mid_index = (len(arr)-1)//2
print(sorted_arr[mid_index])

count_arr = Counter(sorted_arr).most_common()

if len(count_arr) > 1:  # 값이 2개 이상일 때
    if count_arr[0][1] == count_arr[1][1]:  # count가 동일하다면
        print(count_arr[1][0])  # 두번째로 작은 최빈값 출력
    else:
        print(count_arr[0][0])  # 최빈값 출력
else:  # 값이 1개라면
    print(count_arr[0][0])  # 최빈값 출력

print(max(arr)-min(arr))

댓글남기기