[BOJ] 20055 컨베이어 벨트 위의 로봇 (Java)

김도운·2021년 10월 6일
0

알고리즘

목록 보기
12/13

컨베이어 벨트 위의 로봇 문제풀러 가기

알고리즘

시뮬레이션

풀이

우선 문제를 제대로 이해해야 풀 수 있는 문제이다.

  1. stage를 1증가시킨다.
  2. 벨트와 로봇을 모두 회전시킨다.
  3. 로봇을 이동시킨다.
    2-1. '내리는 위치'에 로봇이 있다면, 즉시 로봇을 내린다(로봇을 내린다는 의미는 다음 인덱스로 보낸다는 뜻이 아니라, 벨트 위에서 아예 제거한다는 뜻입니다.)
    2-2. 벨트가 회전하는 방향으로 로봇을 한 칸 이동시킨다(단, 이동시킬 곳의 내구도가 1이상이어야하고, 로봇이 없어야 한다.)
    2-3. 로봇이 위치한 곳의 내구도를 1 감소시킨다.(이 때, 내구도가 0이 되면, 내구도가 0인 곳의 개수를 1 증가시킨다.)
    2-4. '올리는 위치'에 로봇을 놓을 수 있는 조건이라면(내구도 1이상, 올릴 곳에 이미 로봇이 존재하지 않아야됨) 로봇을 놓고, 올라간 곳의 내구도를 1감소시키고, 내구도가 0이된다면 0인 곳의 개수를 1 증가시킨다.
    2-5. '내리는 위치'에 로봇이 존재한다면 로봇을 내린다.
  4. 내구도가 0인 곳의 갯수가 K개 이상이면 그 때까지 진행된 stage값을 출력하고 프로그램을 종료한다.

여기서 가장 헤맨 부분은 '내리는 위치에서 로봇을 내린다'는 부분이었다. 내린다는 의미를 N번째 인덱스에서 N+1번째 인덱스로 이동시킨다라고 해석하면 안되고, N번째 인덱스에 로봇이 있다면 컨베이어 벨트 위에서 내린다 즉, 컨베이어 벨트에서 제거한다라고 해석해야 한다.

코드

import java.io.*;
import java.util.*;

public class Main![](https://velog.velcdn.com/images%2Fkimdon17%2Fpost%2Fc2ee791b-a46a-4689-8934-f8d922c4673e%2F%E1%84%89%E1%85%B3%E1%84%8F%E1%85%B3%E1%84%85%E1%85%B5%E1%86%AB%E1%84%89%E1%85%A3%E1%86%BA%202021-10-06%20%E1%84%8B%E1%85%A9%E1%84%92%E1%85%AE%209.06.49.png) {
	
	static int N, K, stage, zero;
	static int[] belt;
	static boolean[] robot;
	
	public static void main(String[] args) throws Exception{
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		StringTokenizer st;
		
		st = new StringTokenizer(br.readLine());
		N = Integer.parseInt(st.nextToken());
		K = Integer.parseInt(st.nextToken());
		belt = new int[2*N+1];
		robot = new boolean[2*N+1];
		
		st = new StringTokenizer(br.readLine());
		for(int i=1; i<=2*N; i++){
			belt[i] = Integer.parseInt(st.nextToken());
		}
		
		
		zero = 0;
		stage = 0;
		while(true) {
			++stage;							// 각 루프마다 stage 증가 
			
			rotate();							// 컨베이어벨트와 로봇을 둘다 회전시켜 준다.

			moveRobot();						// 로봇을 회전된 벨트에서 이동시킨다. 
			
			if(zero >= K) break;				// 만약 내구도가 0인 곳이 k개 이상이라면 탈출한다. 
			
		}
		System.out.println(stage);
		br.close();
	}

	private static void moveRobot() {
		if(robot[N]) robot[N] = false;			// 내리는 위치에 로봇이 존재한다면 로봇을 그 즉시 내린다. 
												// 내린다는 의미는 N+1로 가는게 아니라 벨트 위에서 아예 제거한다는 뜻

		for(int i=N-1; i>0; i--) {				// 내리는 위치의 이전 인덱스부터 올리는 위치까지 순회하면서 
			if(!robot[i]) continue;				// 만약 현재 인덱스에 로봇이 없다면 다음 위치로 이동 
			
			if(belt[i+1]>0 && !robot[i+1]) {	// 현재 인덱스에 로봇이 있고, 이동시킬 인덱스에 로봇이 없고, 벨트의 내구도가 0 이상이면,  
				robot[i] = false;				// 현재 인덱스의 로봇을 제거하고 
				robot[i+1] = true;				// 다음 인덱스로 이동시킴 
				if(--belt[i+1] == 0) zero++;	// 이동한 곳의 벨트의 내구도를 1 감소시키고, 만약 내구도가 0이 되었다면 zero의 개수를 증가킨다
			}
		}
		
		if(!robot[1] && belt[1]>0) {			// 로봇을 이동시킨 다음, 올리는 위치에 로봇이 없고 벨트의 내구도가 0이 아니면 
			robot[1] = true;					// 올리는 위치에 로봇을 올리고, 
			if(--belt[1] == 0) zero++;			// 올리는 위치의 내구도를 1 감소시키고, 내구도가 0이되었다면 zero 갯수 증가 
		}
		
		if(robot[N]) robot[N] = false;			// 내리는 위치에 로봇이 존재한다면 로봇을 그 즉시 내린다. 
	}

	private static void rotate() {				// 1차원 배열 돌리기
		belt[0] = belt[2*N];					// 마지막 인덱스의 값을 쓰지 않는 0번 인덱스에 저장해두고,  
		for(int i=2*N; i>1; i--) {				// 오른쪽으로 값 슬라이딩 
			belt[i] = belt[i-1];
		}
		belt[1] = belt[0];						// 1번 인덱스에 저장해뒀던 마지막 인덱스의 값을 넣어줌 

		robot[0] = robot[2*N];					// 위와 동일 
		for(int i=2*N; i>1; i--) {
			robot[i] = robot[i-1];
		}
		robot[1] = robot[0];
	}
}
profile
김돈돈

0개의 댓글