알고리즘/Baekjoon

[C++] 백준 5430번 AC

kimyunseok 2022. 5. 12. 21:59
 

5430번: AC

각 테스트 케이스에 대해서, 입력으로 주어진 정수 배열에 함수를 수행한 결과를 출력한다. 만약, 에러가 발생한 경우에는 error를 출력한다.

www.acmicpc.net

문자열 파싱, 자료구조를 이용해서 풀 수 있는 문제.

디테일에서 놓친 부분들이 많아서 틀렸습니다를 많이 받았다.

 

문제풀이

조건을 다음과 같이 해석해서 풀었다.

'덱'을 사용해서 풀고, 현재 방향이 front인지 back인지를 저장한다.

시작의 경우 방향은 front가 된다.

  • 'R' 명령어가 들어왔을 경우 : front / back 방향을 반대로 전환한다.

  • 'D' 명령어가 들어왔을 경우 : 현재 덱에서 방향에 있는 수를 하나 pop한다.
    이 때 덱이 비어있으면 error가 발생하도록 한다.

 

코드 전문

/*
* 백준 5430번 AC
* https://www.acmicpc.net/problem/5430
* 구현 / 문자열 / 파싱 / 자료구조 - 덱
*/
#include <iostream>
#include <deque>

using namespace std;
deque<int> deq;

int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    cout.tie(NULL);

    int tc;
    cin >> tc;
    while (tc--) {
        int numCnt;
        string cmd;
        string numArrStr;
        bool dirIsFront = true;
        bool errorOccur = false;
        cin >> cmd;
        cin >> numCnt;
        cin >> numArrStr;

        int curNum = -1;
        for (int i = 1; i < numArrStr.length(); i++) {
            if (numArrStr[i] >= '0' && numArrStr[i] <= '9') {
                if (curNum == -1) { curNum = 0; }
                curNum *= 10;
                curNum += (numArrStr[i] - '0');
            }
            else if (curNum != -1) {
                deq.push_back(curNum);
                curNum = -1;
            }
        }

        for (int i = 0; i < cmd.length(); i++) {
            if (cmd[i] == 'R') {
                dirIsFront = !dirIsFront;
            }
            else {
                if (deq.empty()) {
                    errorOccur = true;
                    break;
                }

                if (dirIsFront) {
                    deq.pop_front();
                }
                else {
                    deq.pop_back();
                }
            }
        }

        if (errorOccur) {
            cout << "error\n";
        }
        else {
            cout << "[";
            while (!deq.empty()) {
                int num = 0;
                if (dirIsFront) {
                    num = deq.front();
                    deq.pop_front();
                }
                else {
                    num = deq.back();
                    deq.pop_back();
                }
                cout << num;

                if (!deq.empty()) { cout << ","; }
            }
            cout << "]\n";
        }
    }

    return 0;
}

매 테스트 케이스마다 각 변수는 다음과 같은 역할을 맡는다.

  • cmd : 명령어 문자열
  • numCnt : 숫자의 개수 (사실 풀이에서 쓰이지는 않는다.)
  • numArrStr : 정수 배열의 문자열 형 ([1,2,3...]과 같은 형태)
  • dirIsFront : 현재 방향이 앞쪽부터인지 보는 변수 (true - 앞 / false - 뒤)
  • errorOccur : 명령어 탐색 시 에러가 발생했는지 여부를 저장하는 변수

 

입력들을 다 받은 후에, 정수 배열의 문자열을 탐색하면서 덱에 변수를 저장한다.

curNum을 이용해서 숫자를 저장해뒀다가 덱에 삽입한다.

  • curNum의 초기값은 -1인데, -1의 경우에는 입력된 숫자가 없다는 뜻이다.
    따라서 숫자가 아닌 입력의 경우에도 curNum이 -1이라면 curNum을 덱에 삽입하지 않는다.

  • 정수 배열 문자열을 탐색하면서
    만일 현재 idx의 문자가 숫자라면 
       1. curNum이 -1의 경우에는 숫자라는 것을 알려주기 위해 0으로 바꾸고
       2. *10을 해주어서 이전 숫자의 자리를 하나 올려준다.
       3. 그리고 현재 숫자를 curNum에 더해준다.

    만일 현재 idx의 문자가 숫자가 아니라면
    curNum이 -1이 아닌 경우(숫자가 입력된 경우)만 덱에 삽입하고
    curNum을 -1로 만들어준다.

 

그리고 명령어 문자열을 탐색하면서

  • 'R'의 경우에는 dirIsFront 변수를 !dirIsFront로 바꿔준다.(방향 전환)

  • 'D'의 경우에는 덱이 비어있다면 errorOccur를 true로 바꿔주고 반복문을 탈출한다.
    덱이 비어있지 않으면 방향에 따라서 덱에서 숫자 하나를 pop한다.

 

출력은 에러가 발생했다면 error를 출력한다.

에러가 발생하지 않았다면 [...]의 형태로 출력해준다.

 

문자열 부분에 대한 처리, 출력에 대한 처리를 잘못해서 처음에 많이 틀렸다.

디테일에 대한 조건을 잘 분석해야겠다.

 

 

GitHub - kimyunseok/cpp: C++로 코딩한 기록들을 담은 Repository입니다.

C++로 코딩한 기록들을 담은 Repository입니다. Contribute to kimyunseok/cpp development by creating an account on GitHub.

github.com