[구현&시뮬레이션] 백준 20055 컨베이어 벨트 위의 로봇

2021. 3. 1. 11:16카테고리 없음

www.acmicpc.net/problem/20055

 

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

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

www.acmicpc.net

수행 시간 : 2시간 50분

난이도 실버 1의 문제였고, 동시에 삼성 SW역량 기출 문제였다. 보통 문제를 구상하는 알고리즘을 짜는데 시간을 1시간 소비한다면, 이 문제는 문제를 이해하는데 1시간 가까이 걸렸다. 결국 문제를 이해하는 것을 포기하고, 단계별로 알고리즘을 구상하여 코딩을 하였는데, 구상하면서 이해하게 된 문제였다. 문제를 풀면서 2가지 오류가 났었는데, 첫번째로는 컨베이어 벨트의 내구도와, 로봇의 여부를 세주는 것을 1부터 세주는 오류를 범했었다. 생각을 해보니 제일 먼저들어온 로봇은 항상 n에 가까이 있으므로 for문을 시행할때, n 부터 검사를 해주는게 맞다.

그리고 전역변수를 함부로 초기화하여 (feat. cnt) cnt 값이 자꾸 이상하게 나왔는데, 앞으로는 무조건 전역변수를 초기화하지말고 쓰이는 함수에서만 초기화 후 사용을 습관화 하여야겠다.

다시 한번 느끼는 거지만, 구현문제는 처음 알고리즘 구상하는 것이 50프로는 먹고 들어간다는 것을 또 한번 경험하였다.

 

#include <iostream>
using namespace std;
int n, k;
int A[201];
int cnt;//내구도
int stage; // 몇단계에서 멈췃나~
bool exist[101]; // 위쪽 벨트의 로봇 있나없나

void rotate() {
	for (int i = n - 1;i > 0;i--) { //로봇이 존재하면 이동시킨다.
		if (exist[i]) {
			exist[i + 1] = true; // 다음 배열을 true로 바꿔줌 이동했으므로,
			exist[i] = false; // 원래있던 배열을 false로 바꿔줌 이동했으므로.
		}
	}
	exist[n] = false;
	// A[] 배열도 회전시켜야됌 (내구도 배열)
	int tmp = A[2 * n]; //A[마지막] 을 A[처음] 으로 올리기위한 변수 
	for (int i = 2 * n; i > 1;i--) {
		A[i] = A[i - 1];
	}
	A[1] = tmp;
}
void robot_moving() {
	for (int i = n - 1; i > 0;i--) {
		if (exist[i] && !exist[i + 1] && A[i + 1] > 0) { // 다음칸의 로봇이 없어야됌 + 다음칸의 내구도가 1이상이여야됌
			exist[i + 1] = true;
			exist[i] = false;
			A[i + 1]--;
		}
	}
	exist[n] = false;
}
void init() {
	if (!exist[1] && A[1] > 0) {
		exist[1] = true;
		A[1]--;
	}
}
int check_A() {
	cnt = 0;
	for (int i = 1;i <= 2 * n;i++) {
		if (A[i] == 0) {
			cnt++;
		}
	}
	return cnt;
}

int main() {
	cin >> n >> k;
	for (int i = 1;i <= 2 * n;i++) {
		cin >> A[i];
	}
	stage = 1;
	while (1) {
		rotate();
		robot_moving();
		init();
		if (check_A() >= k) {
			break;
		}
		stage++;
	}
	cout << stage;
}