코딩테스트/[BOJ] 문제 풀이

백준 17178 줄서기

_JAEJAE_ 2021. 8. 29. 16:38

https://www.acmicpc.net/problem/17178

 

17178번: 줄서기

아이즈원의 팬인 시온이는 드디어 티켓팅에 성공하여 콘서트를 갔다. 콘서트장에 일찍 도착한 시온이는 기대하며 입장을 위해 줄을 섰다. 하지만 아이즈원의 인기대로 시온이를 포함한 많은

www.acmicpc.net

문제

아이즈원의 팬인 시온이는 드디어 티켓팅에 성공하여 콘서트를 갔다. 콘서트장에 일찍 도착한 시온이는 기대하며 입장을 위해 줄을 섰다. 하지만 아이즈원의 인기대로 시온이를 포함한 많은 팬이 줄을 서고 있다. 콘서트의 입장이 시작되었고 입장은 티켓 번호 순서대로 이루어졌다. 하지만 입구에 너무 많은 팬이 몰려 아무도 이동할 수 없는 상황이 되었고, 결국 주최 측에서 인원을 정렬시켜 다음과 같이 간신히 사람 한 줄이 설 수 있는 대기 공간을 만들었다.

주최 측은 번호표 순서대로만 통과할 수 있는 입구를 만들어 두었지만, 줄에서는 마구잡이로 사람들이 기다리고 있다. 대기 공간을 이용하여 입장이 원활히 이루어지도록 하려고 한다. 콘서트장에 사람들이 제대로 들어갈 수 있는지 확인해보자.

사람들은 현재 5명씩 N 줄을 서 있고, 첫 번째 줄 맨 앞사람만 이동이 가능하다. 이 사람은 콘서트장으로 입장할 수도 있고 대기 공간에서 다시 기다릴 수도 있다. 한 줄의 사람이 다 이동했다면 그다음 줄의 사람들이 이동한다. 대기 공간에는 한 줄로만 설 수 있는 공간이 있으며, 마지막에 들어온 사람부터 나갈 수 있다. 나갈 경우 바로 입장해야 하고, 다시 줄로 돌아갈 수는 없다. 티켓은 A-123과 같이 한 개의 대문자 알파벳과 '-', 1000 미만의 자연수의 조합으로 이뤄어져 있다. 만약 수가 7이라면 A-7과 같이 주어진다. 티켓의 순서는 알파벳이 빠른 티켓이 빠르며, 동일하다면 더 적은 수가 더 빠르다. 티켓 번호는 중복되게 주어지지 않는다.

위의 예시를 예로 들면 다음과 같이 모든 사람들이 입장할 수 있다. 그림과는 달리 대기 공간에는 무한히 많은 사람들이 들어올 수 있다는 것에 주의하여야 한다.

입력

첫째 줄에는 줄에서 기다리고 있는 사람들의 줄 수 N이 주어진다. (1 ≤ N ≤ 100)

둘째 줄부터 N 개의 줄에는 한 줄에 서 있는 5명의 티켓 번호가 주어진다.

사람들이 서 있는 순서대로 입력이 주어진다.

출력

모든 사람이 무사히 콘서트장에 입장할 수 있다면 “GOOD”을 출력하고 그렇지 않다면 “BAD”를 출력한다.

예제 입력 1 

1

G-555 B-203 A-102 A-504 C-719

예제 출력 1 

GOOD


[풀이 과정]

- arr : 주어진 티켓 번호를 저장할 덱

- sorted_arr : 주어진 티켓 번호를 정렬하여 저장할 덱

- wait_arr : 대기 공간에 있는 티켓 번호를 저장할 덱

 

1. 주어진 줄 수(n) * 5만큼 티켓 번호를 입력 받아 arr와 sorted_arr에 저장한다.

2. sorted_arr를 오름차순으로 정렬한다. 

3. compare(string a, string b)

- 티켓의 0번째 값이 작은 것을 먼저 정렬

- 티켓의 0번째 값이 같으면 사이즈가 작은 것을 먼저 정렬 (A-4와 A-102의 경우 A-4가 앞에 와야하기때문)

- 티켓의 0번째 값이 같고 사이즈도 같으면 2번부터 사이즈만큼 값을 비교해서 작은 것이 먼저오게 정렬

 

4. arr에 값이 있으면 계속 반복하여 값을 비교한다.

- sorted_arr와 arr의 첫번째 값이 같으면 둘 다 pop시킨다.

- sorted_arr와 arr의 첫번째 값이 같지 않고 wait_arr의 사이즈가 0이면 arr의 첫번째 값을 pop하여 wait_arr에 넣는다.

- sorted_arr와 arr의 첫번째 값이 같지 않고 wait_arr의 사이즈가 0이 아니면 sorted_arr와 wait_arr의 첫번째 값을 비교하여 같으면 pop하고 아니면 arr의 첫번째 값을 pop하여 wait_arr에 넣는다.

 

5. arr가 비었으면 sorted_arr가 비었는지 확인하여 아직 값이 있으면 wait_arr의 값과 비교한다.

 

6. 모든 비교가 끝난 후에 wait_arr가 비었다면 모든 사람들이 콘서트장에 입장한것이므로 GOOD을 출력하고 값이 남아있다면 BAD를 출력한다.


[소스 코드]

#include <iostream>
#include <string>
#include <deque>
#include <algorithm>
using namespace std;

deque<string> arr;
deque<string> sorted_arr;
int n;

bool compare(string a, string b) {
	if (a[0] < b[0]) return true;
	else if (a[0] == b[0]) {
		if (a.size() < b.size()) return true;
		else if (a.size() == b.size()){
			for (int i = 2; i < a.size(); i++) {
				if (a[i] < b[i]) return true;
				else if(a[i] > b[i]) return false;
			}
		}
	}
	return false;
}

int main() {
	cin >> n;

	for (int i = 0; i < n*5; i++) {
			string s;
			cin >> s;
			arr.push_back(s);
			sorted_arr.push_back(s);
	}

	sort(sorted_arr.begin(), sorted_arr.end(), compare);
	
	deque <string> wait_arr;
	while(!arr.empty()){
		if (sorted_arr.front() == arr.front()) {
			sorted_arr.pop_front();
			arr.pop_front();
		}
		else {
			if (wait_arr.size() == 0) {
				wait_arr.push_back(arr.front());
				arr.pop_front();
			}
			else {
				if (wait_arr.back() == sorted_arr.front()) {
					sorted_arr.pop_front();
					wait_arr.pop_back();
				}
				else {
					wait_arr.push_back(arr.front());
					arr.pop_front();
				}
			}
		}
	}
	while (!sorted_arr.empty()) {
		if (wait_arr.back() == sorted_arr.front()) {
			sorted_arr.pop_front();
			wait_arr.pop_back();
		}
		else break;
	}

	if (wait_arr.empty()) cout << "GOOD\n";
	else cout << "BAD\n";
	return 0;
}