TaBo
개척하는 기록
TaBo
전체 방문자
오늘
어제
  • 기록들 (63)
    • Programming (35)
      • Java (19)
      • Servlet&Jsp (4)
      • Spring (4)
      • SpringBoot (1)
      • 기타 (2)
      • BOJ (5)
    • CS (16)
      • 자료구조 (4)
      • 알고리즘 (4)
      • 운영체제 (5)
      • 기본 용어 (3)
    • Project (4)
      • [Spring] 게시판 (4)
    • 나에 대한 기록 (8)

블로그 메뉴

  • Github

인기 글

태그

  • Spring 게시판
  • java
  • 백준
  • 스프링 게시판
  • 자바
  • 운영체제
  • c++
  • spring
  • OS
  • 알고리즘

최근 글

티스토리

hELLO · Designed By 정상우.
TaBo

개척하는 기록

Programming/BOJ

[C/C++] 백준 5430번

2022. 6. 26. 21:58

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

[ 문제 ]

선영이는 주말에 할 일이 없어서 새로운 언어 AC를 만들었다. AC는 정수 배열에 연산을 하기 위해 만든 언어이다. 이 언어에는 두 가지 함수 R(뒤집기)과 D(버리기)가 있다.

함수 R은 배열에 있는 수의 순서를 뒤집는 함수이고, D는 첫 번째 수를 버리는 함수이다. 배열이 비어있는데 D를 사용한 경우에는 에러가 발생한다.

함수는 조합해서 한 번에 사용할 수 있다. 예를 들어, "AB"는 A를 수행한 다음에 바로 이어서 B를 수행하는 함수이다. 예를 들어, "RDD"는 배열을 뒤집은 다음 처음 두 수를 버리는 함수이다.

배열의 초기값과 수행할 함수가 주어졌을 때, 최종 결과를 구하는 프로그램을 작성하시오.

 

[ 입력 ]

첫째 줄에 테스트 케이스의 개수 T가 주어진다. T는 최대 100이다.

각 테스트 케이스의 첫째 줄에는 수행할 함수 p가 주어진다. p의 길이는 1보다 크거나 같고, 100,000보다 작거나 같다.

다음 줄에는 배열에 들어있는 수의 개수 n이 주어진다. (0 ≤ n ≤ 100,000)

다음 줄에는 [x1,...,xn]과 같은 형태로 배열에 들어있는 정수가 주어진다. (1 ≤ xi ≤ 100)

전체 테스트 케이스에 주어지는 p의 길이의 합과 n의 합은 70만을 넘지 않는다.

 

[ 출력 ]

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

 

[ 풀이 ]

얼핏 보기에는 Deque을 활용하여 "R"이 입력될 때마다 뒤집기를 실행하고, "D"가 입력될 때마다 버리기를 실행하면 해결할 수 있는 간단한 문제이구나! 라고 생각할 수 있다.

하지만, 전체 테스트 케이스의 개수 T의 최댓값이 100, p와 n의 최댓값이 100,000이기에 각 R, D가 입력될 때마다 뒤집기와 버리기를 실행하면 "시간 초과"가 발생한다.

 

시간 초과를 방지하기 위해 크게 세 가지 케이스를 두고 문제를 해결했다.

 

(1) p에 포함된  D(버리기)의 수   >   배열에 들어있는 수의 개수 n  이라면 "error" 출력 후 다음 테스트 케이스 진행

 

(2) p에 포함된 R(뒤집기)의 개수가 0, 2, 4, 6... 짝수라면 bool R = false;  즉, 정방향으로 Deque을 읽는다.

       R == false 일 때 D가 입력되면 Deque은 뒤집히지 않은 상태이므로 pop_front()를 한다.

 

(3) p에 포함된 R(뒤집기)의 개수가 1, 3, 5, 7... 홀수라면 bool R = true;  즉, 역방향으로 Deque을 읽는다.

       R == true 일 때 D가 입력되면 Deque은 뒤집힌 상태이므로 pop_back()를 한다.

 

p의 값을 전부 읽어 R의 상태를 구한 후 R == false 이면 정방향으로, R == true 이면 역방향으로 Deque을 읽는다.

 

#include <iostream>
#include <string>
#include <deque>
#include <algorithm>

using namespace std;

int count_D(string& p)
{
	int n = 0;
	for ( int i = 0; i < p.length(); i++ )
	{
		if ( p[i] == 'D')
		{
			n++;
		}
	}
	return n;
}

int main(void)
{
	int T, n_D, n;
	cin >> T;
	
	for ( int i = 0; i < T; i++ )
	{
		string p, x;
		cin >> p;
		n_D = count_D(p);
		deque<int> dq;
		
		cin >> n;
		
		string s = "";
		cin >> x;
		for ( int j = 0 ; j < x.length() ; j++ )
		{
			if ( isdigit(x[j]) )
			{
				s += x[j];
			}
			else
			{
				if ( !s.empty() )
				{
					dq.push_back(stoi(s));
					s = "";
				} 
			}
		}
		
		if ( n_D > n )
		{
			cout << "error" << endl;
			while ( !dq.empty() )
			{
				dq.pop_front();
			}
			continue;
		}
		
		bool R = false;
		
		for ( int z = 0 ; z < p.length(); z++ )
		{
			if ( p[z] == 'R' )
			{
				R = !R;
			}
			else if ( p[z] == 'D' )
			{
				if ( R )
				{
					dq.pop_back();
				}
				else
				{
					dq.pop_front();
				}
			}
		}
		
		cout << "[";
		if ( !R && !dq.empty() )
		{
			for ( deque<int>::iterator it = dq.begin(); it != dq.end(); it++ )
			{
				if ( it == dq.end()-1 )
				{
					cout << *it;
				}
				else
				{
					cout << *it << ",";
				}
			}
		}
		else if ( R && !dq.empty() )
		{
			for (deque<int>::reverse_iterator it=dq.rbegin();it!=dq.rend(); it++)
			{
				if ( it == dq.rend()-1 )
				{
					cout << *it;
				}
				else
				{
					cout << *it << ",";
				}
			}
		}
		cout << "]" << endl;
		
	}
	
	return 0;
}

+ 추가) Deque이 필요한 이유는 R의 상태에 따라 pop_back() or pop_front() 해야하기 때문

+ 추가) 연결리스트로 Deque을 구현하여 해결할 수도 있을 것이다.

저작자표시 비영리 변경금지 (새창열림)

'Programming > BOJ' 카테고리의 다른 글

[Java] 백준 1967번 - 트리의 지름  (1) 2023.04.14
[C/C++] 백준 7576번  (1) 2022.07.16
[C/C++] 백준 2263번  (0) 2022.07.07
[C/C++] 백준 1655번  (0) 2022.06.30
    'Programming/BOJ' 카테고리의 다른 글
    • [Java] 백준 1967번 - 트리의 지름
    • [C/C++] 백준 7576번
    • [C/C++] 백준 2263번
    • [C/C++] 백준 1655번
    TaBo
    TaBo

    티스토리툴바