개발일기

#15 백준 통계학 & 영단어 암기는 괴로워 본문

오류 및 알고리즘정리본

#15 백준 통계학 & 영단어 암기는 괴로워

츄98 2023. 5. 4. 12:43

1. 통계학

 

이 문제를 풀면서 느낀 점: 문제의 조건을 잘 읽자!!ㅋㅋㅋ

맞는 코드를 입력하는데 틀렸다는 채점결과가 이해가 되지 않는 시점에 문제의 조건을 다시 정독했다.

원인은 중앙값에도 round를 쓰고 있었다는 것ㅎㅎㅎ 소수점 반올림은 산술평균에만 해당하는 것인데, 중앙값에도 round를 쓰고 있었으니 오류가 났던 것이다.  round를 빼고 입력하니 맞았다는 채점결과가 잘 나왔다!!

 

풀이는, 최빈값을 두 가지 방법으로 풀어보았다.

 

# 방법1
import sys
input = sys.stdin.readline

cnt = int(input())
num_arr = []
for i in range(cnt):
    num_arr.append(int(input()))

num_arr.sort()

print(round(sum(num_arr)/cnt))  # 산술평균
print(num_arr[cnt//2]) # 중앙값

# 최빈값찾기
dic = dict()
for i in num_arr:
    if i in dic:
        dic[i] += 1
    else:
        dic[i] = 1

often=max(dic.values())
often_dic = []

for i in dic:
    if often == dic[i]:
        often_dic.append(i)

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

# 범위
print(max(num_arr)-min(num_arr))

 

최빈값이 어떻게 구해지는지 원리를 살펴보도록 하자.

input 데이터를  

5  # 데이터 총 수
8
7
7
7
3

이렇게 주었을 때, 

print(f"dict : {dic}")
# 출력값 dict : {3: 1, 7: 3, 8: 1}

이렇게 각 숫자데이터에 해당하는 빈도수가 저장이 된다.

그리고 가장 큰 빈도수를 가진 수를 often_dic 리스트에 저장한다.

print(f"often_dic : {often_dic}")
# 출력값 often_dic : [7]

최빈값이 여러개이면 여러개가 담긴다.

 

 

두 번째로는 counter라는 콜렉션을 사용하여 최빈값을 구해보았다.

 

# 방법2
import sys
from collections import Counter

input = sys.stdin.readline
cnt = int(input())
num_arr = []
for i in range(cnt):
    num_arr.append(int(input()))

num_arr.sort()

print(round(sum(num_arr)/cnt))  # 산술평균
print(num_arr[cnt//2]) # 중앙값

often = Counter(num_arr).most_common(2)
# 빈도수가 높은 숫자 2개 가져오기

# 최빈값
if cnt>1:
    if often[0][1] == often[1][1]:
        print(often[1][0])
    else:
        print(often[0][0])
else:
    print(often[0][0])

# 범위
print(max(num_arr)-min(num_arr))

 

두 번째 풀이도 원리를 하나씩 살펴보자!

방법 1에서와 같은 데이터를 input했을 때, 이와 같다.

print(often)
# 출력값: [(7, 3), (3, 1)]

 

often = Counter(num_arr).most_common(2) 빈도수가 높은 두 개의 숫자를 가져오기 때문에 5개의 숫자를 input했어도 빈도수가 높은 높은 7과 3만이 often 리스트에 담겼다.

 

 

2. 영단어 암기는 괴로워

이 경우도 최빈값 알고리즘을 활용하여 문제를 풀었고, 최빈값 문제풀이가 두 가지 방식으로 가능해서, 이 역시 두 가지 방법으로 풀어보았다.

 

# 방법1
import sys
input = sys.stdin.readline
N, M = map(int, input().rstrip().split()) # 단어 개수, 기준이 되는 길이
word_list = {}

for _ in range(N):
    word = input().rstrip()

    if len(word) < M:
        continue
    else:
        if word in word_list:
            word_list[word] += 1
        else:
            word_list[word] = 1

word_list = sorted(word_list.items(), key = lambda x: (-x[1], -len(x[0]), x[0]))
# x[0]: 단어, x[1]: 단어 빈도수
# -x[1] : 자주 나오는 단어 앞에 배치
# -len(x[0]) : 단어 길이 길수록 앞에 배치
# x[0] : 단어 사전순 정렬
# x[0] 대신 x를 써도 된다.

for i in word_list:
    print(i[0])

 

두 번째 방법은 counter를 사용했다.

# 방법2
from collections import Counter
import sys
input = sys.stdin.readline

n, m = map(int, input().split())
words = []

for i in range(n):
    words.append(input().rstrip())

counter = Counter(words)
most = counter.most_common()

most.sort(key=lambda x:(-x[1], -len(x[0]), x))

for i in range(len(most)):
    if len(most[i][0]) >= m:
        print(most[i][0])