728x90
이 문제는 공집합이 주어졌을 때 여러 연산을 수행하는 프로그램을 만드는 문제이다.
만약 연산의 수가 적은 경우에는 길이가 20인 배열을 만들어서 각 연산을 구현하면 되지만, 연산의 수가 최대 300만 번까지 주어지기 때문에 이를 시간 내에 구현하려면 다른 방식으로 집합을 나타내야 한다.
그래서 여기서는 비트 자료형을 사용해 집합을 나타낸다. 예를 들어 1~20까지 들어갈 수 있는 집합에 3, 5, 7, 9가 들어있으면 이 집합을 비트 표현으로 00000000000101010100로 나타낸다. 즉, 비트 자료형의 각 자리수가 1인 경우 집합 내에 자리수에 해당하는 수가 들어있다는 것을 의미한다.
이렇게 집합을 표현하면 위 문제에서 주어지는 연산을 O(1) 시간 내에 해결할 수 있다. 집합을 표현한 비트 자료형을 S라고 하자. all 연산은 S를 (1<<21)-1로 바꾼다. 1<<21은 1*2=2를 21제곱을 한 결과로, 여기서 1을 빼서 비트 자료형으로 나타내면 1이 20개인 수(11111111111111111111)가 된다. empty 연산은 S를 0으로 바꾼다.
연산에 어떤 수가 동반된 경우 우선 x를 비트 자료형으로 표현한다. add 연산은 S | x, remove x는 S & ~x, check 연산은 S & x, toggle 연산은 S ^ x를 통해 구현한다.
이를 코드로 구현하면 다음과 같다.
import sys
input = sys.stdin.readline
M = int(input())
S = 0
for _ in range(M):
command = input().strip().split()
if command[0] == "all":
S = (1<<21)-1
elif command[0] == "empty":
S = 0
else:
num = 1 << (int(command[1])-1)
if command[0] == "add":
S = S | num
elif command[0] == "remove":
S = S & ~num
elif command[0] == "check":
print(1 if S & num > 0 else 0)
elif command[0] == "toggle":
S = S ^ num
728x90
'알고리즘 문제' 카테고리의 다른 글
백준 2098번 : 외판원 순회 in Python (0) | 2021.06.08 |
---|---|
백준 1311번 : 할 일 정하기 1 in Python (0) | 2021.06.08 |
백준 1766번 : 문제집 in Python (0) | 2021.06.06 |
백준 1005번 : ACM Craft in Python (0) | 2021.06.06 |
백준 2252번 : 줄 세우기 in Python (0) | 2021.06.04 |