본문 바로가기

컴퓨터/백준 알고리즘

백준 알고리즘 5430번: AC [C++]

문제 출처: https://www.acmicpc.net/problem/5430

 

5430번: AC

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

www.acmicpc.net

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. 느낀점

고려해야할 것이 많았지만 백준의 질문 게시판에 도움되는 글들이 많아서 참고하여 쉽게 해결할 수 있었다.