알고리즘

[백준20055] 컨베이어 벨트 위의 로봇 - 자바(JAVA)

사랑박 2023. 7. 19. 11:00

1. 문제

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

 

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

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

www.acmicpc.net

 

2. 풀이

이 문제를 풀 때 첫 번째로 문제를 이해하는데 어려움이 있었고 두 번째로 컨베이어 벨트와 로봇 위치를 어떻게 저장할 것인가 였다.

나는 문제를 이렇게 풀었다.

  1. `컨베이어 벨트 각각의 칸`을 Space라는 클래스를 만들어서 객체로 만들었다.
  2. `컨베이어 벨트`를 Space 클래스를 자료형?으로 가진 ArrayList로 만들었다.
  3. 1~4 동작을 각각 4개의 메소드로 만들었다.
  4. 컨베이어 벨트가 한 칸 회전하는 것을 ArrayList의 마지막 데이터를 떼내서 AraayList의 첫 번째에 삽입하는 것으로 구현했다.

이 문제에서 주의할 점은 1~4 동작중에서 1과 2에서 로봇이 내리는 것을 생각해야 한다는 것이었다.

처음에 1 동작에서 벨트가 돌아갈 때 내리는 것만 생각하다가 헤매었다.

 

+++ 내 코드에서 내구도가 0인 칸을 count하는 과정을 최적화하면 시간을 더 줄일 수 있었을 것 같다...

 

3. 코드

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.ArrayList;

public class Main {

	static int N, K, cnt, result;
	static ArrayList<Space> belt;

	static class Space {
		int durability;
		boolean robot;

		public Space(int durability, boolean robot) {
			this.durability = durability;
			this.robot = robot;
		}
	}

	public static void main(String[] args) throws Exception {

		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

		String[] tmp = br.readLine().split(" ");

		N = Integer.parseInt(tmp[0]);
		K = Integer.parseInt(tmp[1]);

		belt = new ArrayList<>();

		tmp = br.readLine().split(" ");

		for (int i = 0; i < 2 * N; i++) {
			belt.add(new Space(Integer.parseInt(tmp[i]), false));
		}

		cnt = 0;
		result = 0;
		while (K > cnt) {
			result++;
			step_1();
			step_2();
			step_3();
			step_4();
		}

		System.out.println(result);
	}

	public static void step_1() {
		if (belt.get(N - 1).robot) { // 로봇이 있다면
			belt.get(N - 1).robot = false;
		}
		Space tmp = belt.get(2 * N - 1);
		belt.remove(2 * N - 1);
		belt.add(0, tmp);
	}

	public static void step_2() {
		if (belt.get(N - 2).robot) { // 로봇이 있다면
			if (belt.get(N - 1).durability > 0) {
				belt.get(N - 2).robot = false;
				belt.get(N - 1).durability = belt.get(N - 1).durability - 1;
			}
		}
		for (int i = N - 3; i >= 0; i--) {
			if (belt.get(i).robot) { // 로봇이 있다면
				if (belt.get(i + 1).durability > 0 && !belt.get(i + 1).robot) { // 다음 칸에 내구도가 있고 다음칸에 로봇이 없으면
					// 로봇을 옮기자
					belt.get(i).robot = false;
					belt.get(i + 1).robot = true;
					belt.get(i + 1).durability = belt.get(i + 1).durability - 1;
				}
			}
		}
	}

	public static void step_3() {
		if (belt.get(0).durability > 0 && !belt.get(0).robot) { // 벨트에 로봇이 없고, 내구도가 0이상이면
			belt.get(0).robot = true;
			belt.get(0).durability = belt.get(0).durability - 1;
		}
	}

	public static void step_4() { // 내구도 검사
		cnt = 0;
		for (Space sp : belt) {
			if (sp.durability <= 0)
				cnt++;
		}
	}
}