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의 숫자를 더해주었다. '-' 부호가 등장한 이후에 또 '-' 부호가 등장한 경우에는 일반적인 '+' 부호처럼 괄호 없이 빼줬고 '+'가 등장한 경우에는 다음 '-' 부호가 등장하기 전까지 모든 값을 더해준 다음에 처음의 '-' 부호를 적용해서 빼줬다.
엄청 어려운 문제는 아니었지만 종이에 풀지 않고 바로 코딩을 시작해서 자잘한 오류들이 많이 발생했다. 언제나 종이에 먼저 푸는 습관을 들이는게 좋을 것 같다.
'Algorithm > Baekjoon BOJ' 카테고리의 다른 글
[백준][파이썬] 1459번 : 걷기(코드, 해설, 풀이) (0) | 2022.05.06 |
---|---|
[백준][파이썬] 1244번 : 스위치 켜고 끄기(코드, 해설, 풀이) (0) | 2022.05.06 |
[백준][파이썬] 1213번 : 팰린드롬 만들기(코드, 해설, 풀이) (0) | 2022.05.04 |
[백준][파이썬] 1614번 : 영식이의 손가락(코드, 해설, 풀이) (0) | 2022.05.02 |
[백준][파이썬] 2828번 : 사과 담기 게임(코드, 해설, 풀이) (0) | 2022.05.01 |