[5430] AC - 구현/문자열/덱 ★★☆☆ / 복습 ○
[ 문제 ] : https://www.acmicpc.net/problem/5430
5430번: AC
각 테스트 케이스에 대해서, 입력으로 주어진 정수 배열에 함수를 수행한 결과를 출력한다. 만약, 에러가 발생한 경우에는 error를 출력한다.
www.acmicpc.net
[ 문제 접근 ]
문제 이름 답게 풀다 보면 에이씨.. 가 절로 나오는 그런 문제다.
처음 문제를 읽고
① 입력으로 주어진 [1,2,3,4] 을 1 2 3 4 로 split 하는 부분.
② reverse 하는 부분.
이 관건이겠구나. 싶었다.
아래는 내 긴 여정이 담긴 최종 코드다.
어디서 해맸는지 자세하게 기록해보자.
그래도 이 문제 풀고 얻어 간게 몇 가지 있었다 ;)
[ 최종 코드 ]
#include<iostream>
#include<algorithm>
#include<deque>
#include<string>
#include<sstream>
using std::cout; using std::cin;
using std::deque; using std::string;
int n, t;
string p;
string s_arr;
deque<int> split(string input, char delimeter) {
deque<int> answer;
input.erase(input.begin()); //input.erase(0) '[' 지움
input.erase(input.end() - 1); // ']' 지움
std::stringstream ss(input);
string num = "";
while (getline(ss, num, delimeter)) {
answer.push_back(std::stoi(num));
}
return answer;
}
int main() {
std::ios::sync_with_stdio(false);
cin.tie(nullptr); cout.tie(nullptr);
cin >> t;
while (t--) {
cin >> p;
cin >> n;
cin.ignore(10, '\n');
getline(cin, s_arr);
s_arr.erase(s_arr.begin()); //input.erase(0) '[' 지움
s_arr.erase(s_arr.end()-1); // ']' 지움
deque<int> arr = split(s_arr,',');
bool is_error = false;
bool reverse = false;
for (size_t i = 0; i < p.length(); i++) {
if (p[i] =='R') {
//std::reverse(arr.begin(), arr.end());
reverse = !reverse;
}
else {
if (arr.empty()) {
cout << "error\n";
is_error = true;
break;
}
if (reverse) {
arr.pop_back();
}
else {
arr.pop_front();
}
}
}
// 출력
if (!is_error) {
if (arr.empty()) {
cout << "[]\n";
}
else {
cout << "[";
if (reverse) {
for (auto ritr = arr.rbegin(); ritr != arr.rend(); ritr++) {
if (ritr == arr.rend()-1) {
cout << *ritr;
break;
}
cout << *ritr << ",";
}
}
else {
for (int i = 0; i < arr.size(); i++) {
if (i == arr.size() - 1) {
cout << arr[i];
break;
}
cout << arr[i] << ",";
}
}
cout << "]\n";
}
}
s_arr.clear();
}
return 0;
}
자기전에 한 문제만 풀고 자려다가 피 봤다..
차라리 저 틀렸습니다 가 더 좋더라 요샌..

[ Key Point ]
👉 우선 14 ~ 27 split 함수 부터 보자.
deque<int> split(string input, char delimeter) {
deque<int> answer;
input.erase(input.begin()); //input.erase(0) '[' 지움
input.erase(input.end() - 1); // ']' 지움
std::stringstream ss(input);
string num = "";
while (getline(ss, num, delimeter)) {
answer.push_back(std::stoi(num));
}
return answer;
}
input.erase(input.end() - 1); // ']' 지움
' ] ' 지우려고 처음에는 input.erase(input.end()); 이렇게 썼는데 ] 가 지워지지 않았다.
그래서 erase 함수를 급하게 찾아보니
1. iterator erase (const_iterator position);
2. iterator erase (const_iterator first, const_iterator last);
1 번은 pos 의 값 지우는거고, 2번은 first 부터 last 전까지 지우는거다.
나는 1번을 사용해야하니 end() 가 아닌 end()-1을 해야 마지막 원소를 지울 수 있다.
나머지는 평범한 stringstream을 이용한 평범한 split 함수.
👉 원래는 deque 이 아니라 vector를 이용해서 풀었었다. 그러다가 자꾸 오류 나니깐 괜히 벡터 때문인가 싶어서 벡터를 덱으로 바꾼거다.
( 풀고 보니 벡터를 사용하면 시간 초과가 나온다는 글 들을 여럿 봤다.
벡터 원소 삭제시 한 칸씩 땡겨지는데 이 과정이 reverse 와 마찬가지로 O(N) 의 시간복잡도를 가지기 때문. )
<algorithm> 에 있는 reverse 함수를 사용했는데 이러면 시간초과 가 뜬다.
//std::reverse(arr.begin(), arr.end());
reverse = !reverse;
그래서 bool 타입 reverse flag 하나 만들어서 reverse가 true 면 원소를 뒤에서 pop 하고 false면 앞에서 pop 하게끔 구현했다.
if (reverse) {
arr.pop_back();
}
else {
arr.pop_front();
}
👉 계속 오류가 나서 다른 사람 블로그를 보다가 이 부분을 보고 풀 수 있었다.

👉 계속 하는 실수인데 test case 가 여러개 주어질때는 항상 전역변수 초기화하는거 잊지 말자!!
이것 때문에도 몇번 틀렸다.
s_arr.clear();
[ 다른 사람 풀이 ]
ref :: https://koolreview.tistory.com/65
ref ::