boj-2108(통계학)

황윤기·2021년 8월 20일
0

boj 정렬

목록 보기
2/5

진짜 문제는 간단하다.
중등 수학 수준의 기본적인 통계값들을 구해내라는 것...
하지만 컴퓨터로 구현하려니, 신기한 곳에서 자꾸 막혔다.

문제는 이게 끝..

산술평균? 구하는 거 어렵지 않았다.
중앙값? 들어오는 Input 갯수가 홀수란거 안보고 복잡하게 구현했다가, 홀수인거 보고 다시 구했다.
범위? 그냥 max랑 min 빼주면 끝이다.
근데 최빈값.. 저것이 문제다....

처음 시도


dictionary 에 key를 숫자로, value를 갯수로 해서 구현하고, 모든 list를 체크해서 value에 값을 더해주는 방식으로 구성해보았다.
역시, 입력 갯수가 500,000 그리고 for문을 이중으로 돌다보니 O(N2)O(N^2) 의 복잡도 때문에 시간초과가 터졌다.
그래서 코드를 다 지웠다..

두번째 시도


기본 라이브러리인, Collections에 Counter 를 이용해서 구현해보았다.
Counter는 갯수를 세서, dictionary에 내가 따로 구현한 함수처럼 반환을 해주는데, 이걸 쓰려는거보다도, Counter에 most_common() 함수가 가장 많은 순으로 구해주는게 편해서 사용하였다.
그리고 기고만장하게 '최빈값 중 두 번째로 작은 값' 이랬으니 most_common에서 반환되는 dictionary의 두번째 배열값을 반환했는데, 자꾸 틀렸다고 나오는 것이다.

나도 모르는 반례가 있나... 이러고 고민하던 결과, most_common에서 반환된 dictionary를 출력해보니, 정말 most_common만 나오는게 아니라, most_common부터 아래로 쭉 나오더라..
그래서 예를 들면

-3 -3 -2 1 0 이런 input이 들어오게 되면, 당연히 -3이 제일 많으니까! 라고 생각해서, -3에 대한 값만 반환할줄 알았다.. 결과는?

다 반환한다.. default에 해당하는 갯수만큼, most common한것부터 반환하는 것 같았다..
그래서 저걸 가공하는 작업을 시행해줬다.

분명 첫번째 오는 애는 뭐가 됐든, 가장 흔한 value를 가지고 있을거니까, 처음 값을 max 라고 생각하고, 같은 값이 나오는 애들은 다른 list에 추가 해주어서, 정말 common한 애들만 남겨놓게 만들어주었다.
아래는 코드다

from collections import Counter

def most_frequency(sort_num):
    a = Counter(sort_num)
    a = a.most_common()

    max_val = a[0][1] # 첫번째 값을 가장 흔한 갯수로 판단
    tmp = []

    for i in range(len(a)): # 같은 애들만 tmp 리스트에 추가해줘서, 진짜진짜 흔한 애들로만 구성하도록
        if a[i][1] == max_val:
            tmp.append(a[i])
        else:
            break; # 다른 값이 나오면, 이 뒤로는 아닌 애들만 나올거니까 바로 break 시켜줬다
    
    if len(tmp) == 1: # 진짜 max값만 가지고 있는 애들 중에서도 하나만 있는 애들이 있을 수 있으니, 한개만 있으면 바로 반환
        return tmp[0][0]
    else:
        return tmp[1][0]
    
N = int(input())
num_list = []
num_dic = {}
for i in range(N):
    tmp = int(input())
    num_list.append(tmp)


sort_num = sorted(num_list)

avg = round(sum(num_list) / N)
mid = sort_num[len(sort_num) // 2]
most_fre = most_frequency(sort_num)
range_val = max(num_list) - min(num_list)

print("%d" %avg)
print("%d" %mid)
print("%d " %most_fre)
print("%d" %range_val)

맞았습니다..

profile
안녕하십니까

0개의 댓글