For Programmer

백준 2108번 파이썬 문제풀이(정렬 - 통계학) 본문

코팅테스트/백준 문제 모음

백준 2108번 파이썬 문제풀이(정렬 - 통계학)

유지광이 2021. 10. 9. 15:55
728x90

 

정답 코드

import sys
from collections import Counter

n = int(input())

array = []

for _ in range(n):
    a = int(sys.stdin.readline().rstrip()) #sys로 데이터 입력 받기
    array.append(a)

array.sort() #오름차순 정렬해주기 -> 중앙값 구할 때 필요하며 또한 Counter함수의 most_common()을 사용하기 위해선
# 해당배열 순서대로 해당 숫자와 그 숫자가 등장하는 횟수를 같이 튜플형태로 저장해준다. 따라서 오름차순으로 정렬을 미리 해주어야 문제 풀기가 편하다.

# 최빈값 구하기
def mode(array):
    mode_dict = Counter(array)
    modes = mode_dict.most_common()  # 각 숫자와 등장 횟수를 튜플형식으로 저장(숫자,등장횟수) 원배열에 저장되어있는 순서대로 들어간다.

    if len(modes) > 1: 
        if modes[0][1] == modes[1][1]:
            print(modes[1][0])
        else:
            print(modes[0][0])
    else:
        print(modes[0][0])


print(f'{sum(array) / n:0.0f}') #산술평균
print(array[n // 2]) #중앙값
mode(array) #최빈값
print(max(array) - min(array)) #범위

-> 사실 이문제는 실버4문제 치곤 정답률 26%라는 극악의 정답률을 보여준다. 그 이유는 최빈값을 제외한 나머지 값은 금방구하는데 과연 최빈값을 어떻게 구할 것인가에 대한 어려움이 있다.만약 이문제를 Counter함수를 사용하지 않고 직접구현하게 되면 시간초과 발생하기 때문이다.  Counter함수의 most_common() 내장함수를 이용해야 수월하게 문제를 풀 수 있다.  

 

시간초과발생 코드 (위의 코드와 다른점은 Counter 함수의 구현을 직접했다는 차이밖에 없다.)

import sys

n = int(input())

array = []

#입력받기
for _ in range(n):
    a = int(sys.stdin.readline().rstrip())
    array.append(a)

array.sort() #배열 정렬

#최빈값 구하는 함수
def mode(array):
    if len(array) == 1:
        print(array[0])
        return

    array2 = []  # 입력 받은 배열의 숫자와 등장횟수를 저장할 리스트 선언( [[등장횟수,해당 인덱스]] 로 저장 )
	
 #여기서 부터 Counter함수의 most_common() 내장함수 직접구현
    if len(array) != 1:  # 만약 입력받은 배열의 길이가 1이 아니라면
        for i in range(len(array)):  # 해당배열의 길이만큼 돈다
            if i == (len(array) - 1):  # 만약 i가 마지막 인덱스라면
                array2.append([array.count(array[i]), array[i]])  # 리스트에 추가 [[등장횟수,해당 인덱스]]
            elif array[i] != array[i + 1]:  # 만약 i가 마지막인덱스가 아니라면 앞 뒤의 배열의 숫자를 비교해서 다르다면
                array2.append([array.count(array[i]), array[i]])  # 리스트에 추가 [[등장횟수,해당 인덱스]]

    array2.sort(key=lambda a: a[0], reverse=True) #순서를 많이 등장한 순서로 리스트의 정렬을 변경해준다.
    
#여기까지 Counter함수의 most_common() 내장함수 직접구현

    if len(array2) > 1: 
        if array2[0][0] == array2[1][0]:
            print(array2[1][1])
        else:
            print(array2[0][1])
    else:
        print(array2[0][1])



print(f'{sum(array) / n:0.0f}') #산술평균
print(array[n // 2]) #중앙값
mode(array) #최빈값
print(max(array) - min(array)) #범위
728x90
Comments