비어있는 공집합 S가 주어졌을 때, 아래 연산을 수행하는 프로그램을 작성하시오.
add x: S에 x를 추가한다. (1 ≤ x ≤ 20) S에 x가 이미 있는 경우에는 연산을 무시한다.
remove x: S에서 x를 제거한다. (1 ≤ x ≤ 20) S에 x가 없는 경우에는 연산을 무시한다.
check x: S에 x가 있으면 1을, 없으면 0을 출력한다. (1 ≤ x ≤ 20)
toggle x: S에 x가 있으면 x를 제거하고, 없으면 x를 추가한다. (1 ≤ x ≤ 20)
all: S를 {1, 2, ..., 20} 으로 바꾼다.
empty: S를 공집합으로 바꾼다.
첫째 줄에 수행해야 하는 연산의 수 M (1 ≤ M ≤ 3,000,000)이 주어진다.
둘째 줄부터 M개의 줄에 수행해야 하는 연산이 한 줄에 하나씩 주어진다.
check 연산이 주어질때마다, 결과를 출력한다.
입력 | 출력 |
---|---|
26 add 1 add 2 check 1 check 2 check 3 remove 2 check 1 check 2 toggle 3 check 1 check 2 check 3 check 4 all check 10 check 20 toggle 10 remove 20 check 10 check 20 empty check 1 toggle 1 check 1 toggle 1 check 1 | 1 1 0 1 0 1 0 1 0 1 1 0 0 0 1 0 |
예전에 풀었던 문제이지만, 비트 마스킹 문제를 풀기 위해 비트 마스크 알고리즘으로 다시 풀어 보았다.
비트 마스킹이란 배열을 이진수로 이용하는 것이다.
만약 집합 S가 {1} 이라면 → 0b10 이 되는 것이다.
각 자릿수의 비트 값이 집합 원소가 되는 것이다.
add 2라면 0b100 의 값을 집합 S에 넣어줘야 하므로, OR 연산을 진행해준다.
# S = 0b0010
ADD = S | 1 << X #2
# 1 << 2 = 0b1 << 2 = 0b100
# 0b0010
# OR
# 0b0100
# = 0b0110
remove 2 라면 0b100 의 값을 집합 S에서 삭제해줘야 한다.
즉 S의 2번째 비트 값을 0으로 바꿔주는 것이다.
그러기 위해서 2의 비트를 반전시킨 후 S의 비트와 AND연산 해준다.
# S = 0b0110
REMOVE = S & ~(1 << X #2)
# 1 << 2 = 0b1 << 2 = 0b100
# ~0b100 = -0b011
# 0b0110
# AND
# 0b0011
# = 0b0010
check 2 라면 0b100 의 값이 집합 S에 존재하는지 확인한다.
그러기 위해서 2의 비트와 집합 S와 AND 연산 해준다.
# S = 0b0010
CHECK = S & 1 << X #2
# 1 << 2 = 0b1 << 2 = 0b100
# 0b0010
# AND
# 0b0100
# = 0b0000
toggle 1 라면 0b10 의 값이 집합 S에 존재하면 삭제, 존재하지 않으면 삽입 시킨다.
그러기 위해서 XOR 연산을 실행한다.
# S = 0b0010
TOGGLE = S & 1 << X #1
# 1 << 1 = 0b1 << 1 = 0b10
# 0b0010
# XOR
# 0b0010
# = 0b0000
S = {1, 2, ..., 19, 20} 이다.
문제에서 삽입할 수 있는 n 의 범위가 20이므로 모든 비트가 1인 상태이다.
즉 S = -1 인 상태.
S = {} 이다.
모든 비트가 0인 상태이므로 S = 0인 상태.
from sys import stdin
input = stdin.readline
M = int(input())
S = 0
for _ in range(M):
commands = list(input().split())
x = 0
if len(commands) == 2:
cmd = commands[0]
x = int(commands[1])
else:
cmd = commands[0]
if cmd == 'add':
S |= 1 << x
elif cmd == 'remove':
S &= ~(1 << x)
elif cmd == 'check':
if S & 1 << x:
print(1)
else:
print(0)
elif cmd == 'toggle':
S = S ^ (1 << x)
elif cmd == 'all':
S = -1
elif cmd == 'empty':
S = 0