알고리즘/백준 문제풀이

[백준] 2504번 : 괄호의 값 (python 파이썬)

매일_공부 2024. 11. 19. 16:13
반응형

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

 

 

s = list(input())
l = []
failed = False

def merge(l):
    new_l = []
    for i in l:
        if len(new_l) == 0 or type(i) != int:
            new_l.append(i)
            continue
        #i 가 숫자인 경우
        last = new_l.pop()
        if type(last) == int:
            new_l.append(last + i)
        else:
            new_l.append(last)
            new_l.append(i)
    return new_l
  

for i in s:
    if l == []:
        l.append(i)
    elif i == "(" or i == "[":
        l.append(i)
    elif i == ")":
        if l == []:
            failed = True
            break
        else:
            last = l.pop()
            if last == "(":
                l.append(2)
                l = merge(l)

            elif type(last) == int:
                if l == []: # 2) 인 경우
                    failed = True
                    break
                else:
                    second_last = l.pop()
                    if second_last == "(":
                        l.append(last *2)
                        l = merge(l)
                    else:
                        failed = True
                        break

                   
            else:
                failed =True
                break

    elif i == "]":
        if l == []:
            failed = True
            break
        else:
            last = l.pop()
            if last == "[":
                l.append(3)
                l = merge(l)

            elif type(last) == int:
                if l == []: # 2) 인 경우
                    failed = True
                    break
                else:
                    second_last = l.pop()
                    if second_last == "[":
                        l.append(last *3)
                        l = merge(l)
                    else:
                        failed = True
                        break

                   
            else:
                failed =True
                break
if failed or len(l) != 1 or type(l[0]) != int:
    print(0)
else:
    print(l[0])

 

 

 

단순한 스택 문제이다.

 

하지만 난이도는 골드 5였다.

 

확실히 골드 난이도 답게, 제약 조건이 약간 많아 보였다.

 

 

괄호의 종류도 1가지가 아니라, 2가지였고, 각각의 종류에 따라 곱해지는 수도 달랐다.

 

또한 괄호끼리 만났을때, 숫자끼리 만났을 때의 경우도 고려해야 했다.

 

 

처음에는 스택을 사용해서 한번에 모든 경우를 if else 문으로 바꿔 풀려 했지만, 생각보다 오류가 많이 생기고, 중복되는 

코드도 많이 존재했다.

 

입력의 크기가 최대 30이기 때문에, 여러번 살펴봐도 괜찮다는 생각을 하였고,

이 지점에서, 괄호끼리 만났을 경우와, 숫자끼리 만났을 경우를 분리하기로 하였다.

 

따라서 merge라는 함수를 만들어서, 괄호를 만났을 경우 적절한 수행을 하고, merge 함수를 불러, 숫자끼리

겹쳤을 경우, 합치는 과정을 수행하도록 하였다.

 

따라서 

for문에서는 

1. 적절한 괄호인지 체크

2. 괄호가 합쳐지면 2 또는 3 집어넣기

3. 만약 괄호가 합쳐지기 전에 숫자를 만나면, 2 또는 3 곱하기

 

모든 경우를 수행하면, 항상 merge를 불러서, 숫자 두개가 붙어있으면, 더해서 하나로 만드는 과정을 수행했다.

 

이렇게 하면, 1,2,3 번에서 예외 캐이스가 나오지 않게 된다.

 

모든 for문을 돌고 난 후 마지막 예외 캐이스를 생각했다.

 

만약 ( 만 들어왔을 경우와 ((((( 이런 식의 경우, 오류를 감지하지 못하기 때문에,

위 경우의 예외 캐이스를 감지하여 정답을 출력하였다. 

반응형