[백준] 집합(11723) - python

당고누나·2025년 5월 8일
0

coding-test

목록 보기
51/52
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


👩‍💻 내 코드 - list + 조건문

처음 구현했을 때는 따로 알고리즘을 생각하지 않고 무작정 구현해서 풀었다.

m = int(input())
S = []

for i in range(m):
	tmp = input()
    
    if tmp == 'all':
    	S = list(range(1, 21))
    elif tmp == 'empty':
    	S = []
	else:
    	command, number = tmp.split()
        
        if command == 'add' and number not in S:
        	S.append(number)
        elif command == 'remove' and number in S:
        	S.remove(number)
        elif command == 'check':
        	if number in S:
            	print(1)
            elif number not in S:
            	print(0)
       	elif command == 'toggle':
        	if number in S: S.remove(number)
        elif number not in S: S.append(number)

단순히 리스트 + 조건문으로 풀었더니 시간초과가 났다. list는 시간복잡도가 O(n)으로 속도가 느려 오래걸리기 때문에 시간초과가 날 수 밖에 없었다. 그래서 방법을 찾다가 상대적으로 속도가 빠른 set을 사용하거나 비트마스크 알고리즘을 활용해 풀어야 한다는 것을 알았다.

👩‍💻 내 코드 - 비트마스크 알고리즘

import sys
input = sys.stdin.readline

m = int(input())
S = 0

for i in range(m):
    cmd = input().strip().split()

    if cmd[0] == 'add':
        S |= (1 << int(cmd[1]))
    elif cmd[0] == 'remove':
        S &= ~(1 << int(cmd[1]))
    elif cmd[0] == 'check':
        print(1 if S & (1 << int(cmd[1])) else 0)
    elif cmd[0] == 'toggle':
        S ^= (1 << int(cmd[1]))
    elif cmd[0] == 'all':
        S |= (1 << 21)-1
    elif cmd[0] == 'empty':
        S = 0

💡 새롭게 배운 것

  • list는 시간복잡도가 O(n)으로 속도가 느리다.
  • set은 시간복잡도가 O(1)로 리스트보다 속도가 빠르다.
  • 집합 문제는 비트마스크 알고리즘이 효율적!
profile
초심 잃지 말기 🙂

0개의 댓글