2021. 8. 8. 00:01ㆍBaekjoon/제 2회 천하제일 코딩대회 본선
https://www.acmicpc.net/problem/15926
- 문제 요약
첫 줄에 문자열의 길이 n(1<=n<=200,000)이 주어지고, 그 다음 줄에 길이 n의 괄호 문자열이 주어진다.
괄호 문자열에는 조건이 있는데, 아래의 조건들을 만족하면 올바른 괄호 문자열이다.
- 어떤 문자열 x가 올바른 괄호 문자열이라면, (x)도 올바른 괄호 문자열이다.
- 어떤 문자열 x와 y가 올바른 괄호 문자열이라면, xy도 올바른 괄호 문자열이다.
주어진 문자열에서 길이가 가장 길면서 올바른 괄호 문자열인 부분 문자열의 길이를 출력한다.
올바른 괄호 문자열인 부분 문자열을 찾을 수 없는 경우 0을 출력한다.
- 알고리즘 정리
우선 Tast case들을 보면서 알고리즘을 만들어보겠습니다.
Tast case 1
5
(())(
Tast case 2
14
(()))()((()))(
노트에 적힌 글을 보겠습니다.
첫 번째 입출력에서, 맨 처음 위치부터 4개를 잘라낸 (())가 가장 긴 올바른 괄호 문자열이다.
두 번째 입출력에서, 6번째 위치부터 8개를 잘라낸 ()((()))가 가장 긴 올바른 괄호 문자열이다.
여기서 가장 긴 부분 괄호 문자열이 되는 경우를 보면, '('와 ')'의 개수가 같은 것을 볼 수 있습니다.
이를 활용해서 스택에 문자열을 넣으며 반복문을 돌리면 될 것 같습니다.
empty를 활용하여 스택이 비어있냐, 비어있지 않느냐에 따라서 조건문으로 스택에 push, pop을 해주겠습니다.
- 코드 작성
우선 가장 긴 부분 괄호 문자열의 길이를 저장하는 변수 num을 선언하겠습니다.
sum의 최대 크기는 n의 최대 크기와 같으니 그냥 int형으로 선언해도 될 것 같습니다.
#include<cstdio>
#include<iostream>
#include<stack>
#include<algorithm>
using namespace std;
int n,num;
string a;
stack<int>w;
int main(){
cin>>n>>a;
w.push(-1);
for(int i=0;i<n;i++){
if(a[i]=='('){
w.push(i);
}
else{
w.pop();
if(!w.empty()){//비어있지 않다면
num=max(num,i-w.top());
}
else{//비어있다면
w.push(i);
}
}
}
cout<<num;
return 0;
}
처음에 스택을 비워두고 시작해서 런타임 에러가 떠버렸습니다...ㅋㅋ
문제 자체는 간단하네요.
'Baekjoon > 제 2회 천하제일 코딩대회 본선' 카테고리의 다른 글
[BOJ 15924] 욱제는 사과팬이야!! (0) | 2021.07.17 |
---|---|
[BOJ 15927] 회문은 회문아니야!! (0) | 2021.07.15 |