[ 백준 / Python ] S5. 11723 - 집합

박제현·2024년 3월 28일
0

코딩테스트

목록 보기
98/101
post-thumbnail

난이도

문제

비어있는 공집합 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

add 2라면 0b100 의 값을 집합 S에 넣어줘야 하므로, OR 연산을 진행해준다.

# S = 0b0010
ADD = S | 1 << X #2
# 1 << 2 = 0b1 << 2 = 0b100
# 0b0010
# OR
# 0b0100
# = 0b0110

remove

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

check 2 라면 0b100 의 값이 집합 S에 존재하는지 확인한다.
그러기 위해서 2의 비트와 집합 S와 AND 연산 해준다.

# S = 0b0010
CHECK = S & 1 << X #2
# 1 << 2 = 0b1 << 2 = 0b100
# 0b0010
# AND
# 0b0100
# = 0b0000

toggle

toggle 1 라면 0b10 의 값이 집합 S에 존재하면 삭제, 존재하지 않으면 삽입 시킨다.
그러기 위해서 XOR 연산을 실행한다.

# S = 0b0010
TOGGLE = S & 1 << X #1
# 1 << 1 = 0b1 << 1 = 0b10
# 0b0010
# XOR
# 0b0010
# = 0b0000

all

S = {1, 2, ..., 19, 20} 이다.
문제에서 삽입할 수 있는 n 의 범위가 20이므로 모든 비트가 1인 상태이다.
즉 S = -1 인 상태.

empty

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

profile
닷넷 새싹

0개의 댓글