백준 2108번 문제 - 통계학
https://www.acmicpc.net/problem/2108
2108번: 통계학
첫째 줄에 수의 개수 N(1 ≤ N ≤ 500,000)이 주어진다. 단, N은 홀수이다. 그 다음 N개의 줄에는 정수들이 주어진다. 입력되는 정수의 절댓값은 4,000을 넘지 않는다.
www.acmicpc.net
처음 쓴 코드는 아래와 같았다.
n = int(input())
arr = []
for i in range(n):
arr.append(int(input()))
arr.sort()
print(round((sum(arr)/len(arr))))
print(arr[int(len(arr)/2)])
freq = []
freq_max = 0
for num in arr:
if arr.count(num) > freq_max and num not in freq:
freq_max = arr.count(num)
freq = []
freq.append(num)
elif arr.count(num) == freq_max and num not in freq:
freq.append(num)
freq.sort()
if len(freq)<2:
print(freq[0])
else:
print(freq[1])
math_range = arr[len(arr)-1]-arr[0]
if math_range<0:
math_range*=-1
print(math_range)
그리고 시간초과를 먹었다. 주어진 숫자의 최대치가 50만이다보니 최빈값을 찾는 과정에서 파이썬의 느린 시간으로는 해결하기가 어렵다. 이럴 때는 파이썬에서 기본적으로 제공하는 모듈들을 소환해서 해결하는 방법이 있다. 이번에 사용할 것은 Counter다.
Counter는 collections 모듈에 있는 건데 호출은 코드 최상단에 아래와 같은 걸 집어넣으면 된다.
from collections import Counter
그리고 내가 지정한 배열에서 각 값들이 몇 번 나오는지 찾는 코드는 아래와 같다.
freq = Counter(arr).most_common()
그런데 우리는 최빈값이 여러 개 있을 때는 두 번째로 작은 값을 가져와야 한다. 여기서 freq가 어떤 식으로 출력되냐면
5
-1
-2
-3
-1
-2
의 값이 주어질 때
[(-2, 2), (-1, 2), (-3, 1)]
의 정렬된 형태로 출력된다. 이 때 각 소괄호( ) 안의 값들은 왼쪽 값은 많이 등장하는 값들이 무엇인지를 표시하고 오른쪽 값은 그 값이 몇 번 등장하는지를 표현한다.
그므로 이 튜플들의 [0]번째 값이 같은지를 비교해서 같다면 뒤쪽의 값을 출력하면 된다.
if len(freq) > 1:
if freq[0][1] == freq[1][1]:
print(freq[1][0])
else:
print(freq[0][0])
else:
print(freq[0][0])
이런 형태로 출력한 최빈값이 어떤 건지를 분류할 수 있다.
전체적인 코드는 아래와 같다.
from collections import Counter
n = int(input())
arr = []
for i in range(n):
arr.append(int(input()))
arr.sort()
print(round((sum(arr)/len(arr))))
print(arr[int(len(arr)/2)])
freq = Counter(arr).most_common()
print(freq)
if len(freq) > 1:
if freq[0][1] == freq[1][1]:
print(freq[1][0])
else:
print(freq[0][0])
else:
print(freq[0][0])
math_range = arr[len(arr)-1]-arr[0]
if math_range<0:
math_range*=-1
print(math_range)
이렇게 하고 백준에 다시 제출했는데, 또 시간초과가 걸렸다. 이럴 때는 백준 Python 머신이 너무 느린 탓이므로, 언어 설정을 Python3에서 Pypy3로 바꿔서 다시 제출하면 된다. 둘 다 똑같은 Python문법을 쓰므로 문법상에서 큰 문제가 발생할 일은 없다.
그리고 우리가 나중에 코테를 볼 때, 그 때는 이런 경우는 미리 주최측에서 사전에 방지를 할 것이다. 아마도...