[백준/BOJ] 백준 20055번 : 컨베이어 벨트 위의 로봇

2021. 2. 9. 01:01알고리즘 문제풀이

www.acmicpc.net/problem/20055

 

20055번: 컨베이어 벨트 위의 로봇

길이가 N인 컨베이어 벨트가 있고, 길이가 2N인 벨트가 이 컨베이어 벨트를 위아래로 감싸며 돌고 있다. 벨트는 길이 1 간격으로 2N개의 칸으로 나뉘어져 있으며, 각 칸에는 아래 그림과 같이 1부

www.acmicpc.net

회전하는 함수, 로봇이 움직이는 함수, 새로운 로봇을 올리는 함수를 만들고 Check함수를 통해 내구도가 0인 칸의 개수를 셌다. belt에 벨트의 내구도를 저장하였고, check_robot에 해당 위치에 로봇이 있는지 체크하고, robot에 로봇의 위치를 저장했다.

 

코드

#include <iostream>
#include <algorithm>
#include <vector>
#include <utility>
#include <queue>
#include <deque>
#include <map>
#include <cmath>
using namespace std;

int n, k;
vector<int> belt(201, 0); //벨트의 내구도
vector<int> check_robot(201, 0); //해당 위치에 로봇이 있는지 체크
vector <int> robot; //로봇의 위치 저장
vector<int>::iterator it;

void Rotate()
{
	int temp = belt[2 * n];
	for (int i = 2 * n - 1; i >= 1; i--)
		belt[i + 1] = belt[i];

	belt[1] = temp;

	int erase_check = -1;
	for (int i = 0; i < robot.size(); i++)
	{
		int here = robot[i];
		int there = robot[i] + 1;

		if (there == 2 * n + 1)
			there = 1;

		if (there == n) //내려가는 위치일때
			erase_check = i; 

		check_robot[here] = 0; //here에 로봇이 없다고 체크
		robot[i] = there; //i 로봇의 새로운 위치를 처장
	}

	if (erase_check != -1)
	{
		it = robot.begin() + erase_check;
		robot.erase(it); //해당 로봇 지우기
	}

	for (int i = 0; i < robot.size(); i++)
		check_robot[robot[i]] = 1; //새로운 로봇 위치에 로봇이 있다고 체크
}

void Move()
{
	int erase_check = -1;
	for (int i = 0; i < robot.size(); i++)
	{
		int here = robot[i];
		int there = robot[i] + 1;

		if (there == 2 * n + 1)
			there = 1;

		if (check_robot[there] == 1 || belt[there] == 0) //there로 로봇이 움직일 수 없을때
			continue;

		if (there == n) //내려가는 위치일때
			erase_check = i;

		check_robot[here] = 0;

		if (there != n)
			check_robot[there] = 1;

		robot[i] = there;
		belt[there]--; //내구도 감소
	}

	if (erase_check != -1)
	{
		it = robot.begin() + erase_check;
		robot.erase(it); //해당 로봇 지우기
	}

}

void Put()
{
	if (belt[1] >= 1 && check_robot[1] == 0)
	{
		//새로운 로봇 놓기
		check_robot[1] = 1;
		robot.push_back(1);

		belt[1]--;
	}
}

int Check()
{
	int ret = 0;
	for (int i = 1; i <= 2 * n; i++)
	{
		//내구도가 0인 칸의 개수 세기
		if (belt[i] == 0)
			ret++;
	}
	return ret;
}

int main()
{
	cin.tie(NULL);
	ios_base::sync_with_stdio(false);

	cin >> n >> k;


	for (int i = 1; i <= 2 * n; i++)
	{
		int a;
		cin >> a;

		belt[i] = a;
	}

	int cnt = 0;
	while (1)
	{
		cnt++;
		Rotate(); //회전
		Move(); //로봇의 움직임
		Put(); //올라가는 위치에 로봇이 없을때 로봇을 하나 올리기

		if (Check() >= k)
			break;
	}

	cout << cnt;

	return 0;
}