Doby's Lab

백준 26122번: 가장 긴 막대 자석 (C++) 본문

PS/BOJ

백준 26122번: 가장 긴 막대 자석 (C++)

도비(Doby) 2022. 11. 27. 18:39

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

 

26122번: 가장 긴 막대 자석

막대 자석 문자열은 문자 N과 S로만 구성되면서 다음과 같은 조건을 만족하는 문자열이다: 막대 자석 문자열에 등장하는 N의 개수와 S의 개수는 동일하며, 문자열의 앞쪽 절반을 구성하는 문자는

www.acmicpc.net


Level: Silver V

Solved By: Stack, Implementation

 

확실히 다른 분들의 풀이를 보니 더 깔끔한 풀이들이 존재합니다. 스택을 사용할 필요도 없었던 거죠.

급한 마음을 다루는 연습이 필요하다고 생각합니다.

 

풀이는 이렇습니다.

 

문자열을 for문을 통해 탐색하면서 해당 문자에 대한 스택에 1을 담아줍니다. 그리고, 진행을 하면서 앞 전 문자와 다르다면 스택의 크기(= 부분 중복 문자열의 길이)를 v라는 벡터에 담아줍니다.

 

앞 전 문자와 다르다는 것을 확인하기 위해서 flag라는 bool 변수를 통해 확인해줍니다. 그리고, 다르다는 것이 인식된 이후에는 앞 전 문자가 'N'이었다면 'N'에 대한 스택을 모두 비워버립니다. 탐색이 끝난 후에도 두 스택 중 남아있는 것이 있으니 남아있는 스택의 크기를 v에 담아줍니다.

 

그리고, 끝에 0을 v에 담아줍니다. 0을 담아준 이유는 결과 식과 문제에서 제공된 2번째 케이스로 설명할 수 있습니다.

input: 
5
NNNNN
result:
0

다음 결과가 0인 이유는 N만으로는 막대 자석 문자열을 만들 수 없기 때문입니다. 여기까지 설명해도 0을 넣은 이유에 대해 설득이 되지 않습니다. 결과 식을 어떻게 선언했는지에 대해 설명하면 이해가 됩니다.

결과 식을 어떻게 선언했냐면

for(int i = 1; i < v.size(); i++){
    res = max(res, 2 * min(v[i - 1], v[i]));
}

각 문자로만 구성된 길이를 담은 배열 v에서 앞의 값과 현재 값을 비교하여 두 값 중 작은 것을 채택합니다. 왜냐하면 막대 자석 문자열을 만들 때는 N과 S의 개수가 같아야 하기 때문입니다. 그리고 총문자열의 길이는 N과 S 둘 다이기 때문에 * 2를 해주었고, 그중 최댓값을 고르게 했습니다.

 

0을 넣은 이유는 "NNNNN"이 주어진다면, v의 값들을 {5, 0}이 되어있습니다. N만 가지고서는 문자열을 만들 수 없다는 걸 알려줘야 하기 때문에 0을 넣어주었습니다.

#include <iostream>
#include <vector>
#include <stack>
#include <queue>
#include <algorithm>
#define FASTIO ios_base::sync_with_stdio(false); cin.tie(NULL);
#define ll long long
using namespace std;

int K;
string S;

int main(){
    FASTIO
    cin >> K >> S;
    stack<int> n, s;
    vector<int> v; 
    bool flag = false; // n = true, s = false;
    for(int i = 0; i < S.length(); i++){
        if(S[i] == 'N'){
            n.push(1);
            if(!flag){
                v.push_back(s.size());
                while(!s.empty()) s.pop();
            }
            flag = true;
        }
        else if(S[i] == 'S'){
            s.push(1);
            if(flag){
                v.push_back(n.size());
                while(!n.empty()) n.pop();
            }
            flag = false;
        }
    }
    
    if(flag){
        v.push_back(n.size());
    }
    else v.push_back(s.size());
    
    v.push_back(0);
    
    //for(auto i : v) cout << i << ' ';
    //cout << '\n';
    
    int res = 0;
    
    for(int i = 1; i < v.size(); i++){
        res = max(res, 2 * min(v[i - 1], v[i]));
    }
    
    cout << res;
    return 0;
}

 

728x90