sm 기술 블로그
83. 2108(통계학) 본문
import sys
input = sys.stdin.readline
N = int(input())
num = sorted([int(input())for _ in range(N)])
# 산술평균
avg = sum(num)/N
if -1 < avg < 0:
print(0)
else:
print(round(avg))
# 중앙값
midValue = num[N//2]
if -1 < midValue < 0:
print(0)
else:
print(midValue)
# 최빈값
max = 0
arr = [-1]*8001
cnt = 0
arr_repo = []
find_max = 0
if(len(num) == 1):
print(num[0])
else:
for i in num:
arr[i+4000] += 1
for i in range(8001):
if(arr[i] > find_max):
arr_repo.clear()
cnt = 0
find_max = arr[i]
max = i-4000
arr_repo.append(max)
continue
if(arr[i] == find_max):
cnt += 1
arr_repo.append(i-4000)
continue
if(cnt >= 1):
print(sorted(arr_repo)[1]) # 최빈값 여러개면 두번째로 작은 수
else:
print(max)
# 범위
print(num[len(num)-1]-num[0])
문제요약
산술 평균 : N개의 수들의 합을 N으로 나눈 값
중앙값 : N개의 수들을 증가하는 순서로 나열했을 경우 중앙에 위치하는 값
최빈값 : N개의 수들 중 가장 많이 나타나는 값 (같은게 두 개 이상 있으면 작은 값중 두번째)
범위 : N개의 수들 중 최댓값과 최솟값의 차이 를 구하라
해설
자 코드가 엄청 길다.
파이썬 내부 함수중에 위에 네개를 쉽게 구할 수 있는 함수가 있다.
근데 쓰고 싶지 않았다.(자존심이 허락하지 않았다.)
그래서 직접 구현하는데 최빈값이 애를 많이 먹었다.
설명 들어간다.
# 산술평균
avg = sum(num)/N
if -1 < avg < 0:
print(0)
else:
print(round(avg))
# 중앙값
midValue = num[N//2]
if -1 < midValue < 0:
print(0)
else:
print(midValue)
# 범위
print(num[len(num)-1]-num[0])
산술 평균, 중앙값, 범위는 어렵지 않을 것이다.
산술평균과 중앙값에서
주의 해야 할 점은 음수인데 만약 -0.333 이 나오면 -0이나 -1이 나오면 안된다. (그냥 //를 사용하면 -1이 나옴)
따라서 -1 ~ 0은 0이 나오도록 처리해주었다.
# 최빈값
max = 0
arr = [-1]*8001
cnt = 0
arr_repo = []
find_max = 0
if(len(num) == 1):
print(num[0])
else:
for i in num:
arr[i+4000] += 1
for i in range(8001):
if(arr[i] > find_max):
arr_repo.clear()
cnt = 0
find_max = arr[i]
max = i-4000
arr_repo.append(max)
continue
if(arr[i] == find_max):
cnt += 1
arr_repo.append(i-4000)
continue
if(cnt >= 1):
print(sorted(arr_repo)[1]) # 최빈값 여러개면 두번째로 작은 수
else:
print(max)
먼저 값이 하나면 그냥 자신을 출력해주면 된다.
카운팅 정렬에서 영감을 얻어 카운팅 정렬과 비슷한 방법을 사용하였다.
if(arr[i] > find_max):
arr_repo.clear()
cnt = 0
find_max = arr[i]
max = i-4000
arr_repo.append(max)
continue
일단 arr_repo.append(max)를 사용한 이유는 제일 많이 나온 수라고 생각한 수와 빈도 수가 같고 그 이상의 수가 없는 경우가 있다.
예를 들어 1 1 2 3 3 에서 1과 3은 빈도수가 같다.
일단 배열 특성상 1이 먼저 최고 값으로 들어간다.
arr_repo를 선언하지 않는다면 1이 최고구나 하고 끝이다.
1과 같은 수 3이 들어와도 얘는 최고구나 하고 저장해서 처리가 불가능 하다.
따라서 똑같은 수가 나올 수 있기 때문에 append로 추가해주었다.
근데 clear는 왜 했느냐
만약 1 1 2 2 2 가 있다.
처음에는 1이 최빈값이여서 위와 같이 저장 하였다.
근데 2가 더 빈도수가 높다.
따라서 1은 지워줘야 한다.
if(arr[i] == find_max):
cnt += 1
arr_repo.append(i-4000)
continue
if(cnt >= 1):
print(sorted(arr_repo)[1]) # 최빈값 여러개면 두번째로 작은 수
else:
print(max)
최빈값이 만약 같다면 arr_repo에 저장해둔다.
cnt가 1이라는 것은 최빈값이 같은 게 하나 이상 있다는 것이다.
따라서 같은 최빈값들 중에서 두번째로 작은 수를 출력해야한다.
두번 째 작은 수를 출력하는 방법은 오름차순으로 정렬을 하고 1번째 (첫번째 아님) 인덱스 값을 출력해주면 된다.
'문제 > 백준_파이썬' 카테고리의 다른 글
85. 11650(좌표 정렬하기) (0) | 2022.06.15 |
---|---|
84. 1427(소트인사이드) (0) | 2022.06.14 |
82. 10989(수 정렬하기3) (0) | 2022.06.13 |
81. 2751 (수 정렬하기 2) (0) | 2022.06.13 |
80. 2750(수 정렬하기) (0) | 2022.06.12 |