euisblue
4949. 균형잡힌 세상

https://www.acmicpc.net/problem/4949

걸린 시간: 31m08s

문제

세계는 균형이 잘 잡혀있어야 한다. 양과 음, 빛과 어둠 그리고 왼쪽 괄호와 오른쪽 괄호처럼 말이다.

정민이의 임무는 어떤 문자열이 주어졌을 때, 괄호들의 균형이 잘 맞춰져 있는지 판단하는 프로그램을 짜는 것이다.

문자열에 포함되는 괄호는 소괄호("()") 와 대괄호("[]")로 2종류이고, 문자열이 균형을 이루는 조건은 아래와 같다.

  • 모든 왼쪽 소괄호("(")는 오른쪽 소괄호(")")와만 짝을 이뤄야 한다.
  • 모든 왼쪽 대괄호("[")는 오른쪽 대괄호("]")와만 짝을 이뤄야 한다.
  • 모든 오른쪽 괄호들은 자신과 짝을 이룰 수 있는 왼쪽 괄호가 존재한다.
  • 모든 괄호들의 짝은 1:1 매칭만 가능하다. 즉, 괄호 하나가 둘 이상의 괄호와 짝지어지지 않는다.
  • 짝을 이루는 두 괄호가 있을 때, 그 사이에 있는 문자열도 균형이 잡혀야 한다.

정민이를 도와 문자열이 주어졌을 때 균형잡힌 문자열인지 아닌지를 판단해보자.

문제 접근 방법

중간중간 문자들이 섞여있는데 이는 무시하고 괄호만 본다.

그럼 이전 VPS문제와 똑같은 문제가 된다. 다만 괄호가 (), [] 이렇게 두 종류이기 때문에 스택에서 pop할 때 괄호의 종류만 잘 파악하면 된다.

C++ 코드

1#include <bits/stdc++.h> 2using namespace std; 3 4#define ios cin.tie(NULL), ios_base::sync_with_stdio(false) 5#define endl '\n' 6 7int main(){ 8 ios; 9 10 while(1) { 11 string s; 12 string ans = ""; 13 getline(cin, s); 14 15 if(s.size() == 1 && s[0]=='.') { 16 break; 17 } 18 19 stack<char> stk; 20 int size = s.size(); 21 bool found = false; 22 for(int i=0; i<size; ++i) { 23 if((s[i] == ')' || s[i] == ']') && stk.empty()) { 24 cout << "no" << endl; 25 found = true; 26 break; 27 } 28 29 if(s[i]=='(' || s[i]=='[') { 30 stk.push(s[i]); 31 } else if(s[i]==')') { 32 if(stk.empty() || stk.top() == '[') { 33 cout << "no" << endl; 34 found = true; 35 break; 36 } else { 37 stk.pop(); 38 } 39 } else if (s[i] == ']') { 40 if(stk.empty() || stk.top() == '(') { 41 cout << "no" << endl; 42 found = true; 43 break; 44 } else { 45 stk.pop(); 46 } 47 } 48 } 49 50 if(!found) { 51 cout << ( (stk.empty()) ? "yes" : "no" ) << endl; 52 } 53 } 54 55 return 0; 56}

시간 복잡도

  • 문자열의 길이만큼 순회 - O(S), S = 문자열 길이
  • .이 입력될 때까지 N개의 문자열을 입력받음 - N
  • 스택 연산 - O(1)
  • 최종 시간 복잡도: O(N*S), N = 입력 개수; S = 각 문자열의 길이

공간 복잡도

  • 균형잡인 문자열에서 스택에 들어갈 괄호의 개수 - O(S/2), S = 문자열 길이
  • 최종 공간 복잡도: O(S)