[7785] 회사에 있는 사람

 

백준 Silver V | 7785 | Python | 문제 링크

문제 설명

직원들의 출입 로그가 순서대로 주어진다. enter이면 입장, leave이면 퇴장이다. 로그를 전부 처리한 뒤 현재 회사에 남아있는 사람을 역순 알파벳으로 출력한다.

입력

첫째 줄에 로그 수 n (1 ≤ n ≤ 1,000,000)이 주어진다. 이후 n줄에 이름과 enter 또는 leave가 주어진다.

출력

현재 회사에 있는 사람의 이름을 역순 알파벳으로 한 줄에 한 명씩 출력한다.

입출력 예

입력 출력
4
Baha enter
Askar enter
Baha leave
Artem enter
Askar
Artem

나의 풀이

풀이 1 - 버그 4개 들어있던 첫 제출

import sys
input = sys.stdin.readline

num = int(input())
current = {}                               # dict 사용
for _ in range(num):
    record = input().split()
    if record[1] == "enter":
        current[record[0]]                 # 저장 안 함
    if record[1] == "leave":
        if current[record[1]]:             # record[1]은 "leave"
            del current[record[1]]         # "leave" 키 삭제
        else: pass

print("\n".join(current(keys)))            # 문법 오류 다수

구조 자체는 그려졌다. 로그를 읽으면서 입장하면 추가하고, 퇴장하면 제거하면 된다. 그런데 코드를 다시 보니 버그가 한두 개가 아니었다.

버그 1 — 존재 여부만 필요한데 dict를 썼다

이름이 있는지 없는지만 알면 되는 상황이다. key-value 쌍이 필요 없으니 dict보다 set이 맞다. 당장 틀린 건 아니지만 불필요한 복잡도를 끌어들였다.

버그 2 — 입장 처리에서 저장을 안 한다

current[record[0]]

할당 없이 키에만 접근하고 있다. 없는 키면 KeyError가 나고, 있는 키면 값을 읽고 끝이다. current[record[0]] = True처럼 써야 하는 자리였다.

버그 3 — 인덱스를 잘못 썼다

if current[record[1]]:
    del current[record[1]]

record[0]이 이름, record[1]"enter" 또는 "leave"다. 퇴장 처리에서 이름 대신 record[1], 즉 "leave" 문자열로 딕셔너리를 조회하고 삭제하고 있다. 사람 이름이 아니라 "leave"라는 키를 지우는 코드다.

이게 제일 황당했다. 로직은 맞게 생각했는데 인덱스가 뒤바뀌어 있었다.

버그 4 — 출력 문법이 전부 틀렸다

print("\n".join(current(keys)))

세 가지가 동시에 틀렸다. current는 딕셔너리인데 함수처럼 호출하고 있고, keys는 메서드라 keys()로 써야 하고, 역순 정렬도 빠져 있다.

풀이 2 — 1차 수정 후에도 출력이 틀렸다

import sys
input = sys.stdin.readline

num = int(input())
current = set()

for _ in range(num):
    record = input().split()
    if record[1] == "enter":
        current.add(record[0])
    if record[1] == "leave":
        if record[0] in current:
            current.remove(record[0])

print("\n".join(current.keys(), revers=True))

버그 1~3을 고쳐 set으로 바꾸고 인덱스도 잡았다. 그런데 출력에서 또 걸렸다.

set에는 keys()가 없다. dict 전용 메서드다. set은 그 자체로 이터러블이라 sorted(current)로 바로 쓰면 된다. 거기다 reverserevers로 오타까지 냈다.

풀이 3 - 최종 제출 코드

import sys
input = sys.stdin.readline

num = int(input())
current = set()

for _ in range(num):
    record = input().split()
    if record[1] == "enter":
        current.add(record[0])
    if record[1] == "leave":
        current.discard(record[0])

print("\n".join(sorted(current, reverse=True)))

remove() 대신 discard()를 썼다. remove()는 없는 원소를 지우려 하면 KeyError가 나는데, discard()는 없으면 그냥 넘어간다. 로그 데이터가 항상 올바르다는 보장이 없으니 discard()가 더 안전하다. in 체크와 remove()를 따로 쓸 필요도 없어진다.

'CodingTest > BeakJoon' 카테고리의 다른 글

[15649] N과 M (1)  (0) 2026.03.31
[1158] 요세푸스 문제  (0) 2026.03.31
[1920] 수 찾기  (0) 2026.03.24
[2164] 카드2  (0) 2026.03.24
[10845] 큐  (0) 2026.03.24