[ 백준 ] 4889 / 안정적인 문자열

金弘均·2021년 9월 16일
0

Baekjoon Online Judge

목록 보기
172/228
post-thumbnail

# Appreciation

/*
 * Problem :: 4889 / 안정적인 문자열
 *
 * Kind :: Greedy
 *
 * Insight
 * - 일단 주어진 문자열에서 안정적인 문자열은 제거하자
 *   + Stack 을 이용해서 제거해주자
 *     '{' 는 스택에 저장
 *     '}' 는 스택의 top 이 '{' 이면 pop 해주고 그렇지 않으면 스택에 저장
 *     # 이런식으로 안정적이지 않은 문자열을 구하면
 *       }}...}}
 *       {{...{{
 *       }}...}}{{...{{
 *       위의 세가지 꼴의 안정적이지 않은 문자열이 남게 된다
 *       -> 주어지는 문자열의 길이가 항상 짝수이며
 *          '{' 와 '}' 가 한쌍으로 사라지므로
 *          남은 안정적이지 않은 문자열도 항상 짝수이다
 *
 * - 각 꼴을 하나씩 살펴보자
 *   + }}...}} 꼴의 경우
 *     # {}...{} 로 바꾸면 된다
 *       -> ans = len("}}...}}")/2
 *   + {{...{{ 꼴의 경우
 *     # {}...{} 로 바꾸면 된다
 *       -> ans = len("{{...{{")/2
 *   + }}...}}{{...{{
 *     # {}...{}{}...{} 로 바꾸면 된다
 *       이 때, }}...}} 의 길이를 a, {{...{{ 의 길이를 b 라 하면
 *       a 와 b 가 짝수인 경우, 이 전의 경우처럼 각각의 길이의 반을 답에 더해주면 된다
 *       하지만 a 와 b 가 홀수인 경우, 가운데 }{ 가 남게된다
 *       이러한 경우는 }{ => {} 로 해주어야 하므로 2를 더해주어야 한다
 *       -> ans = a/2 + b/2
 *          ans += a%2 + b%2
 *
 * - 이를 일반화 하면,
 *   안정적이지 않은 문자열의 '{' 개수를 lp, '}' 개수를 rp 라 할 때,
 *   ans = lp/2 + rp/2 + lp%2 + rp%2
 *   로 나타낼 수 있다
 *
 * Point
 * - #include <stack> 을 하지 않고도
 *   string 객체의 .pop_back(), .push_back(...) 을 이용해서
 *   문자열을 스택처럼 이용할 수도 있다
 */

# Code

//
//  BOJ
//  ver.C++
//
//  Created by GGlifer
//
//  Open Source

#include <iostream>
#include <stack>

using namespace std;

#define endl '\n'

// Set up : Global Variables
/* None */

// Set up : Functions Declaration
/* None */


int main()
{
    // Set up : I/O
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    // Set up : Input
    int tc = 0; /* 테스트 케이스 번호 */
    while (true) {
        string s; cin >> s;
        if (s.front() == '-') break;
        tc++;

        // Process
        /* lp = 안정적이지 않은 문자열의 '{' 개수
         * rp = 안정적이지 않은 문자열의 '}' 개수 */
        int lp = 0, rp = 0;
        stack<char> st;
        /* '{' 와 '}' 가 만나면 안정적인 문자열 이므로 없애주어
         * 안정적이지 않은 문자열을 구함 */
        for (char c : s) {
            if (c == '{') {
                st.push(c);
                lp++;
            } else {
                if (not(st.empty()) && st.top() == '{') {
                    st.pop();
                    lp--;
                } else {
                    st.push(c);
                    rp++;
                }
            }
        }

        /* 안정적이지 않은 문자열 꼴은
         * }}...}}
         * {{...{{
         * }}...}}{{...{{
         * 꼴 중 하나임 */
         
        /* }}...}} 에서 rp/2 개 만큼 '}' 를 '{' 로 바꾸어주어 안정적인 문자열을 만듦
         * ans += rp/2
         * {{...{{ 에서 lp/2 개 만큼 '{' 를 '}' 로 바꾸어주어 안정적인 문자열을 만듦
         * ans += lp/2
         * 만약 안정적이지 않은 문자열이 여전히 남아있다면 }{ 일 수밖에 없으므로
         * ans += rp%2 + lp%2 */
         
        int ans = 0;
        ans += lp/2; ans += rp/2;
        ans += lp%2; ans += rp%2;

        // Control : Output
        printf("%d. %d\n", tc, ans);
    }
}

// Helper Functions
/* None */
profile
이런 미친 게임을 봤나! - 옥냥이

0개의 댓글