문제 출처: https://www.acmicpc.net/problem/5430
1. 코드
#include <iostream>
#include <string>
#include <deque>
#include <algorithm>
using namespace std;
int main(void)
{
ios_base::sync_with_stdio(false); cin.tie(NULL);
int t;
cin >> t;
while (t--)
{
string command; //명령어 입력
cin >> command;
int n; //입력할 수의 갯수
cin >> n;
deque <int> d; //배열의 요소 입력
string temp; //배열 입력
cin >> temp;
for (int i = 0; i < temp.length(); i++) //배열 요소 덱에 저장
{
bool flag = true;
if (temp[i] == '[' || temp[i] == ',' || temp[i] == ']') continue; //수가 아닐 경우 제외
if (temp[i - 1] >= '0' && temp[i - 1] <= '9') //이전의 요소가 수일 경우
{
int a = d.back() * 10 + temp[i] - '0'; //10배 증가 후 더하고 다시 넣기
d.pop_back();
d.push_back(a);
flag = false;
}
if(flag) d.push_back(temp[i] - '0'); //이전의 수가 없다면 바로 넣기
}
bool e = false; //에러 체크
bool r = true; //반전 명령어 확인
for (int i = 0; i < command.length(); i++) //명령어 수행
{
if (command[i] == 'D')
{
if (d.empty()) { //비어있다면 에러 메세지 출력 후 종료
cout << "error";
e = true;
break;
}
if (!r) d.pop_back(); //반전상태라면 제일 뒤에 있는 값 제외
else d.pop_front(); //아니라면 제일 앞에 있는 값 제외
}
if (command[i] == 'R') r = !r; //반전 여부 결정
}
if (!e) { //에러 메세지가 발생안했다면
cout << '[';
if (!d.empty()) {
if (!r) reverse(d.begin(), d.end()); //반전 상태라면 반전 시킨 후 출력
for (int i = 0; i < d.size() - 1; i++)
cout << d[i] << ",";
cout << d[d.size() - 1];
}
cout << ']';
}
cout << '\n';
}
return 0;
}
2. 풀이
1. 배열의 정보를 문자열로 입력한다.
2. 배열의 정보를 정수만 추출하여 덱에 저장한다.
3. 명령어 R이 입력될 경우 반전 상태만 기록한다.
4. 명령어 D를 입력할 경우 반전 상태일 때 덱의 제일 뒤에 있는 값을 제거해주고 아니라면 제일 앞의 값을 제거한다.
5. 출력 시 반전 상태라면 반전을 시킨 후 출력해준다.
ios_base::sync_with_stdio(false); cin.tie(NULL);
int t;
cin >> t;
while (t--)
우선 테스트 케이스의 횟수를 입력해주고 그 횟수만큼 반복해준다.
string command; //명령어 입력
cin >> command;
int n; //입력할 수의 갯수
cin >> n;
deque <int> d; //배열의 요소 입력
string temp; //배열 입력
cin >> temp;
사용할 명령어와 입력할 배열 요소의 갯수 그리고 배열의 정보를 입력한다.
for (int i = 0; i < temp.length(); i++) //배열 요소 덱에 저장
{
bool flag = true;
if (temp[i] == '[' || temp[i] == ',' || temp[i] == ']') continue; //수가 아닐 경우 제외
if (temp[i - 1] >= '0' && temp[i - 1] <= '9') //이전의 요소가 수일 경우
{
int a = d.back() * 10 + temp[i] - '0'; //10배 증가 후 더하고 다시 넣기
d.pop_back();
d.push_back(a);
flag = false;
}
if(flag) d.push_back(temp[i] - '0'); //이전의 수가 없다면 바로 넣기
}
반복문을 이용하여 덱에 정수를 추출하여 저장하는데 정수가 아닐 경우 continue를 해주고 이전에 수였다면 해당 값에 곱하기 10을 한 뒤 현재 값을 더하고 그 값을 덱에 저장한다.
만약 이전에 수가 없다면 그냥 바로 덱에 저장한다.
bool e = false; //에러 체크
bool r = true; //반전 명령어 확인
for (int i = 0; i < command.length(); i++) //명령어 수행
{
if (command[i] == 'D')
{
if (d.empty()) { //비어있다면 에러 메세지 출력 후 종료
cout << "error";
e = true;
break;
}
if (!r) d.pop_back(); //반전상태라면 제일 뒤에 있는 값 제외
else d.pop_front(); //아니라면 제일 앞에 있는 값 제외
}
if (command[i] == 'R') r = !r; //반전 여부 결정
}
반복문을 이용하여 입력했던 명령어를 수행한다. R을 입력할 경우 r의 NOT 연산을 하여 저장한다. 그리고 D를 입력할 경우 덱이 비어있다면 에러 메세지를 출력 후 반복문을 종료한다. 그게 아니라면 r의 반전 여부를 확인하여 반전 중이라면 덱의 제일 뒤에 있는 값을 제거하지만 반전 상태가 아니라면 제일 앞의 값을 제거한다.
if (!e) { //에러 메세지가 발생안했다면
cout << '[';
if (!d.empty()) {
if (!r) reverse(d.begin(), d.end()); //반전 상태라면 반전 시킨 후 출력
for (int i = 0; i < d.size() - 1; i++)
cout << d[i] << ",";
cout << d[d.size() - 1];
}
cout << ']';
}
cout << '\n';
에러 메세지가 출력되지 않았고, 덱이 비어있다면 []만 출력하고 덱이 비어있지않다면 반전의 여부를 확인하고 반전이라면 덱의 값을 반대로 배치해준다. 그리고 덱의 값을 출력해준다.
3. 느낀점
고려해야할 것이 많았지만 백준의 질문 게시판에 도움되는 글들이 많아서 참고하여 쉽게 해결할 수 있었다.
'컴퓨터 > 백준 알고리즘' 카테고리의 다른 글
백준 알고리즘 16466번: 콘서트 [C++] (0) | 2021.06.27 |
---|---|
백준 알고리즘 2740번: 행렬 곱셈 [C++] (0) | 2021.05.26 |
백준 알고리즘 1021번: 회전하는 큐 [C++] (0) | 2021.05.20 |
백준 알고리즘 1966번: 프린터 큐 [C++] (0) | 2021.05.17 |
백준 알고리즘 11866번: 요세푸스 문제 0 [C++] (0) | 2021.05.16 |