-
[백준] 1541번 잃어버린 괄호Algorithm Study/Python 2021. 7. 27. 01:30
https://www.acmicpc.net/problem/1541
문제
세준이는 양수와 +, -, 그리고 괄호를 가지고 식을 만들었다. 그리고 나서 세준이는 괄호를 모두 지웠다.
그리고 나서 세준이는 괄호를 적절히 쳐서 이 식의 값을 최소로 만들려고 한다.
괄호를 적절히 쳐서 이 식의 값을 최소로 만드는 프로그램을 작성하시오.
입력
첫째 줄에 식이 주어진다. 식은 ‘0’~‘9’, ‘+’, 그리고 ‘-’만으로 이루어져 있고, 가장 처음과 마지막 문자는 숫자이다. 그리고 연속해서 두 개 이상의 연산자가 나타나지 않고, 5자리보다 많이 연속되는 숫자는 없다. 수는 0으로 시작할 수 있다. 입력으로 주어지는 식의 길이는 50보다 작거나 같다.
출력
첫째 줄에 정답을 출력한다.
풀이
이 문제는 - 가 나오는 순간 다음 -가 나올 때까지 괄호를 치는 것이 가장 작은 수를 만들 수 있다.
1번째 풀이
더보기import sys exp = list(map(str, sys.stdin.readline().strip())) answer = 0 flag = False temp = [] for i in exp: if i == '-' and flag is False: temp.append('-') temp.append('(') flag = True elif i == '-' and flag is True: temp.append(')') temp.append('-') temp.append('(') else: temp.append(i) if flag is True: temp.append(')') print(eval(''.join(temp)))
먼저 실제 '('를 식에 넣는 것을 가정하여 구현을 했었다.
처음 -가 나오면 - ( 를 넣고 그 이외의 경우에는 ) - ( 를 넣는 것으로 괄호를 넣고
-가 1번이라도 나온적 있으면 마지막에 )를 넣어줘서 괄호를 완성해줬다.SyntacError가 나왔는데 수가 0으로 시작할 수 있다는 조건을 처리하지 않았기 때문에 101-01과 같은 식을 파이썬 eval에서 처리할 수 없어서 난 문제였다.
1번째 풀이 수정
더보기import sys exp = list(map(str, sys.stdin.readline().strip())) flag = False temp = [] zero_flag = False ## zero_flag = True로 바꾸면 정상 작동 but 코드가 복잡하고 길다. for i in exp: if i == '-' and flag is False: flag = True temp.append('-') temp.append('(') zero_flag = True elif i == '-' and flag is True: temp.append(')') temp.append('-') temp.append('(') zero_flag = True elif i == '+': zero_flag = True temp.append('+') elif zero_flag is True and i == '0': continue else: zero_flag = False temp.append(i) if flag is True: temp.append(')') print(eval(''.join(temp)))
+, -와 같은 연산자가 나온 직후에 0이 나오면 continue를 통하여 무시하고 지나가는 것으로
0으로 시작하는 숫자를 제거해줬다.하지만 이 경우에도 Syntax error가 처음 나왔었는데 이유를 몰랐다.
블로그에 글을 정리하면서 발견했는데 처음 숫자가 0으로 시작되는 경우를 체크를 하지 못했기 때문이다.zero_flag의 초기값을 False로 줬는데 처음부터 True로 주는 것으로 처음 등장하는 0들도 제거하면 문제없이 작동하는 것을 확인했다.
최종 풀이
1번째 풀이 수정본에서 syntax error의 원인을 찾지 못해서 로직 자체를 수정했다.
( 를 직접 넣는다거나 하지 않고 -를 기준으로 문자열을 구분 짓는 것으로 풀이했다.exp = sys.stdin.readline().lstrip().rstrip() exp = exp.split('-') answer = 0 for idx, v in enumerate(exp): exp[idx] = v.split('+')
입력 받은 문자열을 - 기준으로 구분짓고 -로 구분된 문자열들을 다시 +를 기준으로 구분한다.
이렇게되면 데이터가 2차원 리스트 형식으로 들어가게 되는데
입력이 55-50+40이라면 [[55], [50, 40]]가 나오게 된다. 이 경우에 0번에 있는 리스트의 값은 양수이고 나머지 모든 값은
음수이기 때문에 해당 방법을 구현하면for i in exp[0]: answer += int(i) for i in exp[1:]: for j in i: answer -= int(j) print(answer)
0번에 존재하는 항목들은 모두 answer에 + 연산
1번부터 존재하는 항목들은 모두 - 연산을 하면 된다. 01, 0001과 같은 문자열은 int 형변환을 이용하여 처리했다.전체 코드
import sys exp = sys.stdin.readline().lstrip().rstrip() exp = exp.split('-') answer = 0 for idx, v in enumerate(exp): exp[idx] = v.split('+') for i in exp[0]: answer += int(i) for i in exp[1:]: for j in i: answer -= int(j) print(answer)
1번째 풀이 방법 같은 경우에는 조금 더 다듬어서 실제로 괄호를 넣어야하는 경우에 전처리 과정으로 사용할 수 있을 것 같다.
'Algorithm Study > Python' 카테고리의 다른 글
[백준] 1726번 로봇 (0) 2021.07.28 [백준] 1715번 카드 정렬하기 (0) 2021.07.27 [백준] 1476번 날짜 계산 (0) 2021.07.27 [프로그래머스] 2021 카카오 채용연계형 인턴십 02.거리두기 확인하기 (0) 2021.07.21 [프로그래머스] 2021 카카오 채용연계형 인턴십 01.숫자 문자열과 영단어 (0) 2021.07.21