[Python] 백준 알고리즘 공부

[Python] 20920. 영단어 암기는 괴로워

0pinq2 2026. 3. 7. 18:02

문제

화은이는 이번 영어 시험에서 틀린 문제를 바탕으로 영어 단어 암기를 하려고 한다. 그 과정에서 효율적으로 영어 단어를 외우기 위해 영어 단어장을 만들려 하고 있다. 화은이가 만들고자 하는 단어장의 단어 순서는 다음과 같은 우선순위를 차례로 적용하여 만들어진다.

  1. 자주 나오는 단어일수록 앞에 배치한다.
  2. 해당 단어의 길이가 길수록 앞에 배치한다.
  3. 알파벳 사전 순으로 앞에 있는 단어일수록 앞에 배치한다

보다 짧은 길이의 단어의 경우 읽는 것만으로도 외울 수 있기 때문에 길이가 이상인 단어들만 외운다고 한다. 화은이가 괴로운 영단어 암기를 효율적으로 할 수 있도록 단어장을 만들어 주자.


 첫째 줄에는 영어 지문에 나오는 단어의 개수 과 외울 단어의 길이 기준이 되는 이 공백으로 구분되어 주어진다. (, )

둘째 줄부터 번째 줄까지 외울 단어를 입력받는다. 이때의 입력은 알파벳 소문자로만 주어지며 단어의 길이는 을 넘지 않는다.

단어장에 단어가 반드시 1개 이상 존재하는 입력만 주어진다.

풀이

먼저 단어들을 입력받아 리스트에 저장한 뒤, 길이가 m보다 긴 유효한 단어들만 뽑아 새로운 리스트를 만든다. 우선순위 3가지를 차례로 비교하며 정렬해야하므로 람다 식을 이용한 튜플 정렬식을 사용하였다. 유효 단어 리스트에서 각 단어의 개수를 세서 저장하는 리스트는 Counter를 import 해서 사용하였다.

첫 번째 코드

import sys
from collections import Counter

input = sys.stdin.readline

n, m = map(int, input().split())
word = list(sys.stdin.read().split())
valid = [w for w in word if len(w) >= m]
count = Counter(valid)
ans = list(set(valid))
ans.sort(key=lambda x: (-count[x], -len(x), x))
print(*ans, sep="\n")

이제 여기서 속도와 메모리 사용량 측면에서 조금 더 효율적으로 개선할 수 있는 부분들을 수정해 보았다.

 

1. sys.stdin.read().split()로 입력을 아예 한 번에 받은 뒤 처리

: 기존에는 n, m은 따로 입력받고 map으로 처리하였지만 sys.stdin.read().split()로 그냥 한 번에 모든 입력을 받은 뒤 리스트의 인덱스를 활용하여 n, m에 값을 집어넣었다. 이로 인해 input = sys.stdin.readline 을 선언할 필요가 없어졌다. 

 

2. list(set(valid)) 대신 list(count) 사용

: list(set(valid))를 사용하게 되면 valid 리스트를 전체 순회하면서 set을 생성해야 한다. 하지만 count의 key에 이미 중복되지 않은 단어들이 저장되어 있기 때문에 list(count)를 사용하면 한 번에 key 묶음을 가져올 수 있다.


3. valid 리스트를 리스트 슬라이싱 상태에서 바로 생성

: 기존에는 단어 배열을 word라는 리스트에 저장한 뒤 그 리스트를 활용해 리스트 컴프리헨션을 했지만, 이제는 한 번에 모든 입력을 다 받으므로 앞의 n, m을 제외한 상태인 [2:] 로 바로 리스트 컴프리헨션을 했다.

 

최종 코드

import sys
from collections import Counter

data = sys.stdin.read().split()
n, m = int(data[0]), int(data[1])
valid = [w for w in data[2:] if len(w) >= m]
count = Counter(valid)
ans = list(count)
ans.sort(key=lambda x: (-count[x], -len(x), x))
print(*ans, sep="\n")
코드가 조금 더 효율적이어졌고, 실행시간과 코드 길이, 메모리 사용량 모두 개선되었다.
불필요한 로직은 최대한 생략하도록 하자.

 

배운 것

  • (key=lambda x: (-count[x], -len(x), x)): 튜플의 각 값 앞에 -을 붙이면 그 값에 대하여 내림차순 정렬을 하게 된다.
  • sys.stdin.read().split(): 첫 번째 코드에서는 이 전체를 list()로 한 번 감쌌는데, split() 자체가 리스트를 반환하므로 굳이 그럴 필요가 없었다...
  • print(*ans, sep="\n"): sep="..." 는 구분자를 의미한다. sep="\n"을 넣으면 리스트의 각 원소가 줄바꿈되어 출력된다.

 

 

'[Python] 백준 알고리즘 공부' 카테고리의 다른 글

[Python] 21921. 블로그  (0) 2026.03.09
[Python] 2512. 예산  (0) 2026.03.08
[Python] 13305. 주유소  (0) 2026.03.06
[Python] 2164. 카드2  (0) 2026.03.06
[Python] 17266. 어두운 굴다리  (0) 2026.03.01