본문 바로가기

Algorithm/Baekjoon BOJ

[백준][파이썬] 1541번 : 잃어버린 괄호(코드, 해설, 풀이)

반응형

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

 

1541번: 잃어버린 괄호

첫째 줄에 식이 주어진다. 식은 ‘0’~‘9’, ‘+’, 그리고 ‘-’만으로 이루어져 있고, 가장 처음과 마지막 문자는 숫자이다. 그리고 연속해서 두 개 이상의 연산자가 나타나지 않고, 5자리보다

www.acmicpc.net

 


- 문제

 

  주어진 입력 수식에서 원하는 부분에 괄호를 쳐서 가장 작은 값을 출력할 수 있도록 만드는 문제다. 

예제 입력 1 : 55-(50+40) = -35

예제 입력 2 : 10+20+30+40 = 100

예제 입력 3 : 00009-00009 = 0

 


- 해설

 

  주어진 수식을 숫자랑 부호로 구분한 다음에 괄호를 기준으로 생각하면 크게 3가지 경우가 있는 것을 알 수 있다.

 

1. 마이너스가 없는 경우

: '+' 밖에 없으므로 어떻게 괄호를 치더라도 같은 값이 나온다.

 

2. 마이너스랑 플러스가 섞인 경우

: '-'가 등장하기 이전에는 상관이 없지만, '-'가 하나라도 등장하면 그 이후의 모든 '+'는 괄호를 쳐서 묶어주도록 한다.

1-(2+3)+4 = 0보다 1-(2+3+4)=-8로 더 작은 값이 나오기 때문이다.  

 

3. 마이너스만 있는 경우

: 모두 '-'이면 괄호 없이 마이너스가 없는 경우와 마찬가지로 값을 구하면 된다.(마이너스만 있는 경우에는 괄호를 치면 오히려 출력 값이 커질수가 있음)

 

 


- 풀이

import sys
import re
givenNum = sys.stdin.readline().strip()     # 입력값
signs = [] 
for i in range(len(givenNum)):
    if not givenNum[i].isnumeric():         # 부호만 따로 분류
        signs.append(givenNum[i])
nums = re.split('[+|-]', givenNum)          # 숫자끼리 분류
nums = list(map(int, nums))
answer = nums[0]
temp = 0
i = 0
isAdded = False
while(i < len(signs)):
    if signs[i] == '-':                     # 부호가 '-'인데
        for j in range(i+1, len(signs)):
            if signs[j] == '-':             # 다음 부호도 '-'이면
                answer -= (nums[j])
                isAdded = False
                break
            else:                           # 다음 부호도 '+'이면
                nums[j+1] += (nums[j])
                i += 1
                isAdded = True
        if isAdded:                         # 부호가 '-+++'와 같이 '-'가 다시 나타나지 않으면
            answer -= nums[i+1]
            isAdded = False
    else:                                   # 부호가 '+'이면
        answer += (nums[i+1])
    if i == len(signs)-1 and signs[i] == '-':   # 마지막 부호가 '-'이면
        answer -= nums[i+1]
    i += 1
print(answer)

1. 문자열 분류 방법

: 문자열.isnumeric()을 통해 해당 문자열이 숫자인지 파악하여 숫자가 아닌 경우는 부호밖에 없으므로 부호를 분리하였고 일반 문자열.split()의 경우에는 구분자를 한 번에 하나 밖에 적용할수가 없기 때문에 re.split()을 사용하였다. re.split()은 여러 개의 구분자를 사용하고 싶을 때 사용하는 것으로 re.split(1번째 매개변수, 2번째 매개변수)로 사용이 가능하다. 1번째 매개변수로는  '[a|b|c|d]'와 같은 방식(구분자가 a이거나 b이거나 c이거나 d)으로 사용할 수 있고 2번째 매개변수로는 문자열을 주어야 한다.

 

2. 반복문 이용 방법

: 부호가 3개이면 구분된 숫자는 무조건 (부호의 개수 + 1)이기 때문에 부호의 길이를 기준으로 반복문을 돌리고 '+' 부호가 등장하면 해당 index의 숫자와 index+1의 숫자를 더해주었다. '-' 부호가 등장한 이후에 또 '-' 부호가 등장한 경우에는 일반적인 '+' 부호처럼 괄호 없이 빼줬고 '+'가 등장한 경우에는 다음 '-' 부호가 등장하기 전까지 모든 값을 더해준 다음에 처음의 '-' 부호를 적용해서 빼줬다.

 

  

  엄청 어려운 문제는 아니었지만 종이에 풀지 않고 바로 코딩을 시작해서 자잘한 오류들이 많이 발생했다. 언제나 종이에 먼저 푸는 습관을 들이는게 좋을 것 같다. 

반응형