

문제 출처 : https://www.acmicpc.net/problem/11723
난이도 : 실버 5
집합 S는 1부터 20까지의 정수만 담을 수 있다.
명령이 M개 주어지고, 아래 연산을 수행한다.
add x : S에 x 추가remove x : S에서 x 제거check x : x가 있으면 1, 없으면 0 출력toggle x : x가 있으면 제거, 없으면 추가all : S를 {1..20}으로 만들기empty : S를 공집합으로 만들기⚠️ 포인트: M이 최대 3,000,000이라서
연산도 중요하지만, 특히 입출력(입력/출력 방식) 때문에 시간/메모리 이슈가 쉽게 난다.
check 결과를 out = []에 쌓아두면
명령이 수백만 개일 때 출력 문자열이 너무 커져서 메모리 초과가 날 수 있다.
그래서 check가 나올 때마다 sys.stdout.write()로 즉시 출력한다.
import sys
input = sys.stdin.readline
write = sys.stdout.write
# 명령의 개수
M = int(input())
# 집합 S (1~20만 들어갈 예정)
s = set()
# all 명령을 빠르게 처리하기 위해 미리 만들어 둠
ALL = set(range(1, 21))
for _ in range(M):
# 한 줄을 "명령 + (숫자)" 형태로 받는다.
# 예) "add 3" -> ["add", "3"]
# 예) "all" -> ["all"]
cmd = input().split()
op = cmd[0] # 명령어
if op == "add":
# add x : 집합에 x 추가
x = int(cmd[1])
s.add(x)
elif op == "remove":
# remove x : 집합에서 x 제거
# discard는 x가 없어도 에러가 안 나서 안전
x = int(cmd[1])
s.discard(x)
elif op == "check":
# check x : 있으면 1, 없으면 0 출력
# ⚠️ 출력 결과를 리스트에 모으면 메모리 초과가 날 수 있어서 바로 출력
x = int(cmd[1])
if x in s:
write("1\n")
else:
write("0\n")
elif op == "toggle":
# toggle x : 있으면 제거, 없으면 추가
x = int(cmd[1])
if x in s:
s.remove(x) # 여기서는 존재가 확실하니 remove 사용해도 안전
else:
s.add(x)
elif op == "all":
# all : {1..20}으로 만들기
# copy를 써서 ALL 자체가 변하는 걸 방지
s = ALL.copy()
else: # op == "empty"
# empty : 공집합으로 만들기
s.clear()
set으로 풀 수 있고, 메모리 초과는 출력 누적(out 리스트) 때문에 발생한다.
그래서 check는 결과를 모으지 말고 sys.stdout.write()로 바로 출력하면 된다.