https://www.acmicpc.net/problem/1541
- 어렵지 않은 전형적인 그리디 알고리즘 문제였다.
< 잃어버린 괄호 >
[문제]
세준이는 양수와 +, -, 그리고 괄호를 가지고 식을 만들었다. 그리고 나서 세준이는 괄호를 모두 지웠다.
그리고 나서 세준이는 괄호를 적절히 쳐서 이 식의 값을 최소로 만들려고 한다.
괄호를 적절히 쳐서 이 식의 값을 최소로 만드는 프로그램을 작성하시오.
[입력]
첫째 줄에 식이 주어진다. 식은 ‘0’~‘9’, ‘+’, 그리고 ‘-’만으로 이루어져 있고, 가장 처음과 마지막 문자는 숫자이다. 그리고 연속해서 두 개 이상의 연산자가 나타나지 않고, 5자리보다 많이 연속되는 숫자는 없다. 수는 0으로 시작할 수 있다. 입력으로 주어지는 식의 길이는 50보다 작거나 같다.
[출력]
첫째 줄에 정답을 출력한다.
예제 입력 | 예제 출력 |
55-50+40 | -35 |
10+20+30+40 | 100 |
00009-00009 | 0 |
아이디어
뺄셈 기호가 한 번 나온다면 다음 뺄셈이 나오기 전까지 괄호를 친다고 생각해보았고, 그렇게 되면 최대한 많이 뺄 수 있다. 최대한 많이 빼면 최솟값을 얻을 수 있게 된다.
즉, 뺄셈 기호가 나온 순간부터는 모조리 빼주면 된다.
풀이 및 코드
calculation = input()
# operation : 1 or -1 덧셈인지 뺄셈인지
operation = 1
# num : 한 수 저장
num = 0
# result : 결과 저장
result = 0
for c in calculation:
if (ord('0') <= ord(c) <= ord('9')):
# 큰 자리부터 읽기 때문에 10 곱해 한 자리씩 올려주고 1의자리에 해당하는 숫자를 더해줌
num *= 10
num += ord(c) - ord('0')
elif (c == '+' or c == '-'):
# 부호가 나온 것은 수의 끝이므로 result에 더해줌
result += operation * num
# num 초기화
num = 0
if (c == '-'):
# -부호 뒤부터는 모조리 빼줌
operation = -1
# 마지막에 한 번 더 더해줘야 마지막 수도 계산됨.
result += operation * num
print(result)
덧셈과 뺄셈을 따로 구현하기보다, operation변수를 사용해 1이나 -1을 곱해서 더해주었다.
만약 123을 인식한다고 생각해보자. 처음에 1을 num에다가 더해주고, for문에서 c가 2일 때, 1 * 10 + 2를 해준 것이다. 그렇게 num에는 12가 저장된다. c가 3일 때는 똑같이 12 * 10 + 3을 해주면 123을 저장하게 된다. int함수를 이용해 문자열을 정수로 변환시켜줄 수 있었지만, 42서울에서 하던 것 처럼 c언어로도 구현이 가능하게끔 해보고 싶었다. 하지만, c언어로 구현한다면 문자열 맨 마지막 부분에 \0(널문자)가 오기 때문에 마지막임을 인식할 수 있지만 파이썬은 그러지 않기 때문에 마지막 한 번 더 더해주는 작업을 해 주어야 끝의 수도 계산해줄 수 있다.
'공부 > 백준' 카테고리의 다른 글
[백준] 9935번 문자열 폭발 (Python) (0) | 2023.01.06 |
---|---|
[백준] 13305번 주유소 (Python) (0) | 2023.01.05 |
[백준] 11399번 ATM (Python) (0) | 2023.01.04 |
[백준] 1931번 회의실 배정 (Python) (0) | 2023.01.04 |
[백준] 11047번 동전 0 (Python) (0) | 2023.01.04 |