Koala - 2기/C반

[BOJ] 2346번. 풍선 터뜨리기

Buzz_BEAR 2021. 2. 18. 09:30
 

2346번: 풍선 터뜨리기

첫째 줄에 자연수 N(1≤N≤1,000)이 주어진다. 다음 줄에는 차례로 각 풍선 안의 종이에 적혀 있는 수가 주어진다. 편의상 0은 적혀있지 않다고 가정하자.

www.acmicpc.net

큐, 덱으로는 돌아가는 식의 문제를 내는 것이 국룰인것 같습니다.

이 문제도 반전 요세푸스와 풀이 과정은 비슷하나, 첫 입력 인덱스를 기억해야 한다는 것이 까다롭습니다.

그래서 pair<비교할 수, 첫 입력 인덱스>로 덱에 입력을 받겠습니다. 

비교할 때는 first를 통해 비교하고, 출력할 때는 second를 출력할 것입니다. 

 

[정답코드 보기]

#include <iostream>
#include <algorithm>
#include <cmath>
#include <vector>
#include <string>
#include <stack>
#include <queue>
#include <map>
#include <unordered_set>
using namespace std;

int main()
{
	ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);

	deque<pair<int, int> > dq;
	int n, temp, next_target=0;

	cin >> n;
	for (int i = 1; i <= n; i++)
	{
		cin >> temp;
		dq.push_back(make_pair(temp, i));
	}

	cout << dq.front().second << " ";
	next_target = dq.front().first;
	dq.pop_front();

	while (!dq.empty())
	{
		if (0 < next_target)
		{
			for (int i = 1; i < next_target; i++)
			{
				dq.push_back(dq.front());
				dq.pop_front();
			}
			cout << dq.front().second << " ";
			next_target = dq.front().first;
			dq.pop_front();
		}
		else
		{
			next_target *= -1;
			for (int i = 1; i < next_target; i++)
			{
				dq.push_front(dq.back());
				dq.pop_back();
			}
			cout << dq.back().second << " ";
			next_target = dq.back().first;
			dq.pop_back();
		}
	}
    return 0;
}

[코드 설명 보기]

	deque<pair<int, int> > dq;
	int n, temp, next_target=0;

	cin >> n;
	for (int i = 1; i <= n; i++)
	{
		cin >> temp;
		dq.push_back(make_pair(temp, i));
	}

	cout << dq.front().second << " ";
	next_target = dq.front().first;
	dq.pop_front();

요 부분이 이 코드의 요약본 같은 부분입니다.

 

우선 dq라는 덱에 {입력 수, 입력 인덱스}를 저장합니다.

첫번째 풍선은 터트리고 시작하므로 second에 해당하는 입력 인덱스를 출력하고, 다음 터트릴 타겟 풍선으로 first에 해당하는 입력 수를 저장합니다.

 

	while (!dq.empty())
	{
		if (0 < next_target)
		{
			for (int i = 1; i < next_target; i++)
			{
				dq.push_back(dq.front());
				dq.pop_front();
			}
			cout << dq.front().second << " ";
			next_target = dq.front().first;
			dq.pop_front();
		}
		else
		{
			next_target *= -1;
			for (int i = 1; i < next_target; i++)
			{
				dq.push_front(dq.back());
				dq.pop_back();
			}
			cout << dq.back().second << " ";
			next_target = dq.back().first;
			dq.pop_back();
		}
	}
    return 0;
}

이후로는 양 방향으로 도는 원형 큐입니다.

유의할 부분으로는 다음 타겟이 음수일 때, next_target에 -1을 곱해주었습니다.

어차피 절댓값만큼만 움직여주면 되니까요!

이후로는 일반적인 원형 큐처럼 동작합니다.