🤖 알고리즘

BOJ 2800. 괄호 제거

키루루 2023. 3. 29. 23:34

🔎 BOJ 2800. 괄호 제거 (골드5)

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

 

2800번: 괄호 제거

첫째 줄에 음이 아닌 정수로 이루어진 수식이 주어진다. 이 수식은 괄호가 올바르게 쳐져있다. 숫자, '+', '*', '-', '/', '(', ')'로만 이루어져 있다. 수식의 길이는 최대 200이고, 괄호 쌍은 적어도 1개

www.acmicpc.net

 

💡 SOL

import sys
import copy

#1 : 입력
A = list(sys.stdin.readline().strip())
gual = []
stack = []

#2 : stack으로 괄호 쌍 처리 / gual 리스트에 괄호쌍의 인덱스 위치 저장
for i in range(len(A)):
    if A[i] == '(':
        stack.append(i)
    elif A[i] == ')':
        gual.append([stack.pop(), i])

#3 : gaul 리스트의 모든 괄호쌍에 대해 부분집합 생성하여 부분집합 해당 괄호쌍만 제거하고 answer 리스트에 추가
answer = []
for i in range(1, 1<<len(gual)):
    A_copy = copy.deepcopy(A)
    for j in range(len(gual)):
        if i & (1<<j):
            A_copy[gual[j][0]] = ""
            A_copy[gual[j][1]] = ""
    answer.append(''.join(A_copy))

#4 : answer 중복제거 + 사전순 정렬(문제조건) 하여 출력
answer = sorted(list(set(answer)))
for a in answer:
    print(a)

 

 

💭 TIL

비트연산자 부분집합 생성

  • 1<<n = 2^n
    • 원소 n개인 집합의 각각 0/1(불포함/포함) 모든 경우의 수
  • a & b
    • a와 b의 교집합
    • 예를 들어, a = 101, b = 001일 때 True / a = 101, b = 010 일 때 False
  • ex) A = [1, 2, 3] 일 때
n = len(A)

for i in range(1<<n):      # n개 집합의 0/1 모든 경우의 수
    for j in range(n):     # 각 자리수를 나타냄 (n번째 원소)
        if i & (1<<j):
            pass           # 해당 부분집합의 경우에 대한 연산

 

문제 조건 주의 !!

"어떤 식을 여러 쌍의 괄호가 감쌀 수 있다." 

 → 생성된 문자열들 중 중복 있을 수 있으므로 제거해야 함.