🌟 통계학
조건
시간 제한 | 메모리 제한 | 제출 | 정답 | 맞힌 사람 | 정답 비율 |
2 초 | 256 MB | 153426 | 36506 | 29278 | 26.143% |
문제
첫째 줄에 수의 개수 N(1 ≤ N ≤ 500,000)이 주어진다. 단, N은 홀수이다. 그 다음 N개의 줄에는 정수들이 주어진다. 입력되는 정수의 절댓값은 4,000을 넘지 않는다.
수를 처리하는 것은 통계학에서 상당히 중요한 일이다. 통계학에서 N개의 수를 대표하는 기본 통계값에는 다음과 같은 것들이 있다. 단, N은 홀수라고 가정하자.
- 산술평균 : N개의 수들의 합을 N으로 나눈 값
- 중앙값 : N개의 수들을 증가하는 순서로 나열했을 경우 그 중앙에 위치하는 값
- 최빈값 : N개의 수들 중 가장 많이 나타나는 값
- 범위 : N개의 수들 중 최댓값과 최솟값의 차이
N개의 수가 주어졌을 때, 네 가지 기본 통계값을 구하는 프로그램을 작성하시오.
입력
첫째 줄에 수의 개수 N(1 ≤ N ≤ 500,000)이 주어진다. 단, N은 홀수이다. 그 다음 N개의 줄에는 정수들이 주어진다. 입력되는 정수의 절댓값은 4,000을 넘지 않는다.
출력
첫째 줄에는 산술평균을 출력한다. 소수점 이하 첫째 자리에서 반올림한 값을 출력한다.
둘째 줄에는 중앙값을 출력한다.
셋째 줄에는 최빈값을 출력한다. 여러 개 있을 때에는 최빈값 중 두 번째로 작은 값을 출력한다.
넷째 줄에는 범위를 출력한다.
예제 입력 1
5
1
3
8
-2
2
예제 출력 1
2
2
1
10
풀이 계획
각 요구사항들을 함수로 구현하자. 산술평균, 중앙값, 범위는 문제없이 구했는데 최빈값 구하는 부분에서 헤맸다. 입력받은 수들 중 중복되는 값들을 제거한 리스트에서 하나씩 돌면서 몇개인지 세고 그중 가장 많은 수를 가진 값들을 다시 뽑아내서 그 중에 두번째로 작은 값을 고르는 방식이었다. 다음과 같이 구현하고자 했었다.
def Mode(num):
count, max_count = [], []
num_dup = list(set(num))
for i in range(len(num_dup)):
count.append(num.count(num_dup[i]))
for j in range(len(count)):
if count[j] == max(count):
heapq.heappush(max_count, num_dup[j])
if len(num) > 1 and len(max_count) > 1:
heapq.heappop(max_count)
return min(max_count)
계산 결과는 잘 나왔지만, 선언되는 배열들과 반복문이 많고 힙큐를 다루는 탓에 시간초과가 발생했다. 찾아보던 중 Counter 클래스를 사용하여 빈도를 계산할 수 있다는 사실을 알게 되었다. Counter 객체는 각 발생 횟수를 포함하는 딕셔너리처럼 동작한다. counts.values()에서 가장 빈번한 발생 횟수를 max() 메소드로 찾고 List comprehension을 사용하여 counts의 각 항목에서 최빈값에 해당하는 요소들을 찾는다. 이들을 리스트에 추가하고, sorted() 함수를 사용하여 리스트를 정렬한다. 이렇게 하면 최빈값들이 정렬된 순서로 저장된다. 만약 최빈값이 여러 개인 경우, 최빈값들 중에서 두 번째로 작은 값을 반환하도록 한다. 그렇지 않은 경우에는 최빈값들 중에서 유일한 값을 반환한다.
풀이
import sys
from collections import Counter
read = sys.stdin.readline
def Mean(num): # 산술 평균
return int(round(sum(num) / len(num), 0))
def Median(num): # 중앙값
sorted_num = sorted(num)
return sorted_num[int(len(num) / 2)]
def Mode(num): # 최빈값
counts = Counter(num)
max_count = max(counts.values())
mode_values = sorted([value for value, count in counts.items() if count == max_count])
return mode_values[1] if len(mode_values)>1 else mode_values[0]
def Scope(num): # 범위
return max(num) - min(num)
def solution():
n = int(read())
num = [int(read()) for _ in range(n)]
print(f"{Mean(num)}\\n{Median(num)}\\n{Mode(num)}\\n{Scope(num)}")
solution()
'백준 알고리즘' 카테고리의 다른 글
[BOJ] 백준_1920번_수 찾기_Python3 (2) | 2023.12.07 |
---|---|
[BOJ] 백준_10815번_숫자카드_Python3 (1) | 2023.12.06 |
[BOJ] 백준_9094번_수학적 호기심_Python3 (0) | 2023.12.03 |
[BOJ] 백준_13305번_주유소_Python3 (0) | 2023.12.02 |
[BOJ] 백준_10448번_유레카 이론_Python3 (0) | 2023.12.01 |
포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!