문자열 파싱, 자료구조를 이용해서 풀 수 있는 문제.
디테일에서 놓친 부분들이 많아서 틀렸습니다를 많이 받았다.
문제풀이
조건을 다음과 같이 해석해서 풀었다.
'덱'을 사용해서 풀고, 현재 방향이 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를 출력한다.
에러가 발생하지 않았다면 [...]의 형태로 출력해준다.
문자열 부분에 대한 처리, 출력에 대한 처리를 잘못해서 처음에 많이 틀렸다.
디테일에 대한 조건을 잘 분석해야겠다.
'알고리즘 > Baekjoon' 카테고리의 다른 글
[C++] 백준 3055번 탈출 (0) | 2022.05.17 |
---|---|
[C++] 백준 16562번 친구비 (1) | 2022.05.16 |
[C++] 백준 23290번 마법사 상어와 복제 (0) | 2022.04.25 |
[C++] 백준 1043번 거짓말 (0) | 2022.04.05 |
[C++] 백준 17298번 오큰수 (0) | 2022.04.05 |