티스토리 뷰

PS/BOJ Python

11723번 - 집합

zpqmdh 2023. 6. 25. 02:05

https://www.acmicpc.net/problem/11723

 

11723번: 집합

첫째 줄에 수행해야 하는 연산의 수 M (1 ≤ M ≤ 3,000,000)이 주어진다. 둘째 줄부터 M개의 줄에 수행해야 하는 연산이 한 줄에 하나씩 주어진다.

www.acmicpc.net

정말.. 많은 시간초과가 났다...

틀린 이유에는 두 가지가 있었는데

1) check, toggle 에서 copy를 통해 새로운 집합을 생성한 후 비교

정말 비효율적인 코드라고 생각한다. 만약 길이로 비교를 하고 싶었다면, 기존 집합 S에 더해보고 길이가 같으면 1을 출력하고 다르다면 0을 출력한 뒤 다시 remove 하면 되는데 생각이 짧았던 것 같다.

 

2) 아래의 데이터셋에 잘못된 결과를 냄

2
all
check 20

이거는 https://www.acmicpc.net/board/view/115855 링크에서 확인한 반례이다. all 연산을 할 때 S 집합에 원소를 1~20으로 다시 지정해주는데, int형식으로 넣고 check 연산에서는 str타입으로 받은 값과 비교를 하니 당연히 1이 아니라 0이 출력되었다.

따라서 이 두 가지를 효율적으로 수정하여 통과한 최종적인 코드는 아래와 같다.

 

# 집합
import sys
input = sys.stdin.readline

S = set()
M = int(input())

for _ in range(M):
    cmd = input().split()
    if cmd[0] == 'add':
        S.add(int(cmd[1]))
    elif cmd[0] == 'remove':
        S.discard(int(cmd[1]))
    elif cmd[0] == 'check':
        if int(cmd[1]) in S:
            print(1)
        else:
            print(0)
    elif cmd[0] == 'toggle':
        if int(cmd[1]) in S:
            S.discard(int(cmd[1]))
        else:
            S.add(int(cmd[1]))
    elif cmd[0] == 'all':
        S = set([i for i in range(1, 21)])
    elif cmd[0] == 'empty':
        S = set()

하지만 이 문제는 집합 자료형으로 푸는 것이 아니라 비트 마스크로 푸는 것이 더 올바른 방법이다.

최소한의 연산으로 풀 수 있기 때문이다.

비트마스크로 푸는 방법은 아래의 링크에 자세한 설명이 있어 첨부한다.

https://hooongs.tistory.com/208

 

[백준11723번] 집합 / Python3

문제 비어있는 공집합 S가 주어졌을 때, 아래 연산을 수행하는 프로그램을 작성하시오. add x: S에 x를 추가한다. (1 ≤ x ≤ 20) S에 x가 이미 있는 경우에는 연산을 무시한다. remove x: S에서 x를 제거

hooongs.tistory.com

 

'PS > BOJ Python' 카테고리의 다른 글

17298번 - 오큰수  (0) 2023.07.14
10986번 - 나머지 합  (0) 2023.07.12
9935번 - 문자열 폭발  (0) 2023.06.22
1932번 - 정수 삼각형  (0) 2023.06.10
11660번 - 구간 합 구하기 5  (0) 2023.06.05
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/11   »
1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
글 보관함