[백준] 11899번: 괄호 끼워넣기_실버3 (Python)
https://www.acmicpc.net/problem/11899
11899번: 괄호 끼워넣기
첫 번째 줄에 S를 올바른 괄호열으로 만들기 위해 앞과 뒤에 붙여야 할 괄호의 최소 개수를 출력합니다. 불가능한 경우는 주어지지 않습니다.
www.acmicpc.net
문제
심심한 승현이는 너무 심심한 나머지 올바른 괄호열을 가지고 놀고 있었습니다.
(()(()))()()
그러다가 어쩌다 보니 괄호열을 부러뜨렸습니다.
(() (( )))() ()
크게 낙담한 승현이는 노력해 보았지만, 대부분이 부러져 버려 단 한 부분만 재사용할 수 있다는 것을 깨닫게 되었습니다.
)))()
승현이는 이 괄호열을 가지고 놀려고 했으나 올바른 괄호열이 아니기 때문에 행복하지 않았습니다. 이를 보던 지학이는 승현이에게 “그러면 앞과 뒤에 적절하게 괄호를 붙이면 올바른 괄호열이 되지 않을까?”라고 했고, 승현이는 조금 생각한 뒤 그렇게 하기로 했습니다. 예를 들어, 위의 올바르지 않은 괄호열의 경우 앞에 여는 괄호 3개를 붙이면 올바른 괄호열이 됩니다.
((()))()
그러나 괄호열을 사서 붙이는 데에는 돈이 들고 많이 붙일수록 놀기가 불편해지기 때문에, 승현이는 가능한 한 괄호열을 적게 추가하려고 합니다.
승현이가 망가뜨리고 사용 가능한 올바르지 않은 괄호열이 주어질 때, 올바른 괄호열로 만들기 위해 앞과 뒤에 붙여야 할 괄호의 최소 개수를 구하는 프로그램을 작성하세요.
입력
첫 번째 줄에 올바르지 않은 괄호열 S가 주어집니다. S의 길이는 1 이상 50 이하입니다.
출력
첫 번째 줄에 S를 올바른 괄호열로 만들기 위해 앞과 뒤에 붙여야 할 괄호의 최소 개수를 출력합니다. 불가능한 경우는 주어지지 않습니다.
예제 입력 1 복사
)))()
예제 출력 1 복사
3
예제 입력 2 복사
)(()
예제 출력 2 복사
2
예제 입력 3 복사
))()((
예제 출력 3 복사
4
예제 입력 4 복사
)(()(()))
예제 출력 4 복사
1
힌트
괄호열이란 여는 괄호 ‘(’와 닫는 괄호 ‘)’로만 구성된 문자열을 말합니다.
올바른 괄호열은 아래와 같이 정의할 수 있습니다.
- "()"는 올바른 괄호열입니다.
- A가 올바른 괄호열이라면 "(A)" 역시 올바른 괄호열입니다.
- A와 B가 모두 올바른 괄호열이라면 "AB" 역시 올바른 괄호열입니다.
출처
bracket = list(input())
bracket_stack = []
for i in range(len(bracket)):
if bracket[i] == '(':
bracket_stack.append(bracket[i])
elif bracket[i] == ')' and '(' in bracket_stack:
bracket_stack.append(bracket[i])
bracket_stack.remove('(')
bracket_stack.remove(')')
else:
bracket_stack.append(bracket[i])
print(len(bracket_stack))
'(' 와 ')' 를 입력받았을 때로 크게 두 상황으로 나눈 뒤에,
'('를 입력받으면 일단 빈 스택에 넣어주고
')'를 입력받았는데 스택에 '('가 있으면 일단 입력받은 ')'도 스택에 넣어주고 '('와')'가 한 세트가 되었기 때문에 스택에서 삭제를 해준다.
'('를 입력받았는데 ')'가 없다면 스택에 추가해 준다
그렇게 세트들은 삭제해 주고 스택에 남은 괄호들은 다 짝이 필요한 괄호들이기 때문에 스택의 길이를 출력해 주면 된다.
처음에 생각했던 방법은 살짝 잔머리를 써서 여는 괄호 '('와 닫는 괄호 ')'의 개수만 비교해서 출력을 해봤지만
그렇게 되면 괄호 검사가 제대로 작동하지 않는다.. 그래서 스택을 이용한 괄호 검사 알고리즘을 변형하여 풀었더니 어렵지 않게 풀 수 있었다.
다시 생각을 고쳐서 코드를 작성하고서는 elif 부분을 아래처럼 작성했었는데 예제 3개만 제대로 출력이 되고
마지막 예제에서 ')'를 제거하는 부분에서 오류가 나서 다시 해결방법을 생각했다.
elif bracket[i] == ')' and '(' in bracket_stack:
bracket_stack.remove(')')
생각을 해보니 ')'만 삭제를 하면 될게 아니라 ()이 괄호가 한 세트이기 때문에 '('도 같이 삭제를 해줘야 하는데 애초에
'('를 입력받았을 때 append를 해주지 않았기 때문에 '('를 제거하는 데에서 오류가 났던 거다.
추가 수정 ▼
elif bracket[i] == ')' and '(' in bracket_stack:
bracket_stack.pop()
어차피 '('가 마지막에 위치할 거니까 굳이 입력받은 ')'를 append 해준 뒤 두 개를 따로 삭제하지 말고 스택에 남아있는 '('만 pop을 해주면 더 간단하다.
bracket = list(input())
bracket_stack = []
for i in range(len(bracket)):
if bracket[i] == '(':
bracket_stack.append(bracket[i])
elif bracket[i] == ')' and '(' in bracket_stack:
bracket_stack.pop()
else:
bracket_stack.append(bracket[i])
print(len(bracket_stack))