문제
심심한 승현이는 너무 심심한 나머지 올바른 괄호열을 가지고 놀고 있었습니다.
(()(()))()()
그러다가 어쩌다 보니 괄호열을 부러뜨렸습니다.
(() (( )))() ()
크게 낙담한 승현이는 노력해 보았지만, 대부분이 부러져 버려 단 한 부분만 재사용할 수 있다는 것을 깨닫게 되었습니다.
)))()
승현이는 이 괄호열을 가지고 놀려고 했으나 올바른 괄호열이 아니기 때문에 행복하지 않았습니다. 이를 보던 지학이는 승현이에게 “그러면 앞과 뒤에 적절하게 괄호를 붙이면 올바른 괄호열이 되지 않을까?”라고 했고, 승현이는 조금 생각한 뒤 그렇게 하기로 했습니다. 예를 들어, 위의 올바르지 않은 괄호열의 경우 앞에 여는 괄호 3개를 붙이면 올바른 괄호열이 됩니다.
((()))()
그러나 괄호열을 사서 붙이는 데에는 돈이 들고 많이 붙일수록 놀기가 불편해지기 때문에, 승현이는 가능한 한 괄호열을 적게 추가하려고 합니다.
승현이가 망가뜨리고 사용 가능한 올바르지 않은 괄호열이 주어질 때, 올바른 괄호열으로 만들기 위해 앞과 뒤에 붙여야 할 괄호의 최소 개수를 구하는 프로그램을 작성하세요.
입력
첫 번째 줄에 올바르지 않은 괄호열 S가 주어집니다. S의 길이는 1 이상 50 이하입니다.
출력
첫 번째 줄에 S를 올바른 괄호열으로 만들기 위해 앞과 뒤에 붙여야 할 괄호의 최소 개수를 출력합니다. 불가능한 경우는 주어지지 않습니다.
https://www.acmicpc.net/problem/11899
이 문제에서 중요한 부분은 바로, 스택으로 ()를 입력해 나가면서 더 필요한 괄호의 개수를 어떤식으로 파악하냐! 이다.
단순하게 cnt 변수로 +- 를 쓰게되면
)(()
이런 예제의 경우 0으로 출력되게 되지만 실제 출력의 형태는 '2'로 이루어져야 한다.
따라서 필자의 경우 두 괄호가 반대로 겹치는 과정인 ")("가 생기게 될 경우 앞의 괄호 ')'를 붙여주는 '('이 없을 경우 cnt값을 1씩 추가해나가는 과정을 통해서 코딩하였다.
또한 이 문제의 경우 필수적으로 '스택'이라는 자료구조에 대한 이해가 필요한데, 바로 선입선출 구조를 통한 입력값을 저장함으로써 문제의 답을 구해낼 수 있기 때문이다.
혹시 스택이라는 개념과 구현이 잘 이해가 안된다면 필자의 다음 포스팅을 참고하길 바란다.
https://romancurity.tistory.com/1
[자료구조 기초] 스택의 개념과 구조, 구현
데이터를 저장하기 위한 자료구조의 형태로는 여러가지가 존재하는데 그 중 대표적인 스택과 큐중 스택에 대해서알아보자.스택이란?먼저 스택의 대표적인 특징은 데이터의 입력과 출력 순서가
romancurity.tistory.com
다음으로는 필자가 작성한 코드를 살펴보도록 하겠다.
#include <stdio.h>
#include <string.h>
#define max 100000
typedef struct Stack{
int data[max];
int top;
int cnt;
// <>로 이루어진 문자열의 경우
}Stack;
void init(Stack *s)
{
s->top= 0;
s->cnt = 0;
}
void add(Stack *s, char word)
{
if(word=='(')
{s->top+=1;}
else if(word==')' && s->top<=0)
{s->cnt+=1;}
else
{s->top-=1;}
}
int print(Stack *s)
{
s->cnt+=s->top;
printf("%d", s->cnt);
return 0;
}
int main()
{
Stack s;
init(&s);
char word[max];
scanf("%s", word);
int len = strlen(word);
for(int i=0; i<len; i++)
{
add(&s, word[i]);
}
print(&s);
return 0;
}
기본적으로 Stack의 구현과정은 굉장히 기본적인 init과 add, print함수만으로 구성되었기에 쉽게 이해할 수 있을 것이다.
다만 이중에서 이 문제의 핵심인 ")("와 같이 괄호의 순서에 따라 필요한 괄호의 개수를 구하는 부분을 어떻게 풀이하였는지는 자세히 설명해보겠다.
void add(Stack *s, char word)
{
if(word=='(')
{s->top+=1;}
else if(word==')' && s->top<=0)
{s->cnt+=1;}
else
{s->top-=1;}
}
add함수가 관련내용을 구현한 코드인데, 먼저 "("로 시작한 경우 s->top값을 통해 판별해낼수 있기에 바로 s->top+=1;로 처리하였다, 중요한 부분은 ')'로 시작하는 문자를 어떻게 판단하는지였는데, 이 부분은 바로 앞에서 처리한 s->top값을 이용해서 판별하였다.
- 여는 괄호 (이면 top을 증가시켜 누적
- 닫는 괄호 )인데 top <= 0이면, 대응할 여는 괄호가 없으므로 추가해야 하는 여는 괄호 → cnt++
- 닫는 괄호 )인데 top > 0이면, 짝이 맞으므로 top--
이 문제를 통해 꼭 챙겨가야할 항목은
1. 스택의 구현과 구조
2. ")(" 와 "()" 같이 괄호의 순서가 다를때 판별방법
라고 볼수 있겠다.
'알고리즘 풀이(백준)' 카테고리의 다른 글
백준 18258번 : 큐 2 #C (0) | 2025.04.04 |
---|---|
백준 1735번: 분수 합 #C (0) | 2025.04.03 |
백준 11047번 : 동전 0 #C (0) | 2025.04.02 |
백준 1100번 : 하얀 칸 #C (0) | 2025.04.01 |