[백준] 20055번 컨베이어 벨트 위의 로봇 - Java

yseo14·2025년 4월 28일

코딩테스트 대비

목록 보기
77/88

문제 링크

풀이

컨베이어 벨트를 LinkedList로 구현하여 풀었다.
문제에서 요구하는 움직임을 4개의 메서드로 나누었다.

  • 전체 컨베이어 벨트 회전
  • 로봇의 이동
  • 내리는 위치에서 로봇 내리기
  • 올리는 위치에 로봇 올리기

전체 컨베이어 벨트 회전
단순하게 제일 뒤 칸을 제일 앞으로 옮겨주기만 하면 된다.

//  벨트 회전 메서드
public static void rotateBelt() {
	conveyor.addFirst(conveyor.removeLast());
}

로봇의 이동
컨베이어 벤트의 아래 부분은 로봇이 없으므로 윗부분만 생각하면 된다.
윗부분의 제일 마지막(내리는 위치)에는 어차피 로봇이 없으므로 n-2번째부터 1번째까지 반복문을 돈다.

  • 현재 칸에 로봇이 없는 경우
  • 다음 칸에 로봇이 있거나 내구도가 1보다 작은 경우
    위 경우에는 이동할 수 없다.

이동 가능할 경우 다음 칸의 내구도를 감소시키고 로봇을 이동시킨다.
이동 후에 해당 칸이 내구도가 0이 되면 내구도가 0인 칸의 수를 의미하는 변수인 brokenBelt를 증가시킨다.

로봇이 내리는 위치로 이동하는 경우 즉시 내린다.

public static void moveRobots() {
        for (int i = n - 2; i > 0; i--) {
            Belt curr = conveyor.get(i);
            Belt next = conveyor.get(i + 1);
            if (!curr.isRobotOn) {  //  현재 칸에 로봇이 없으면 패스
                continue;
            }
            if (next.isRobotOn || next.durability < 1) {    //  다음 칸에 로봇이 있거나 내구도가 없어도 패스
                continue;
            }

            //  다음 칸으로 이동할 수 있으면
            next.durability--;  //  다음칸 내구도 감소
            next.isRobotOn = true;  //  다음칸으로 로봇 이동
            curr.isRobotOn = false;

            if (next.durability == 0) { //  이동한 칸이 내구도가 0이면
                brokenBelt++;   //  내구도 0인 칸 수 증가
            }

            if (i + 1 == n - 1) {   //  로봇이 내리는 위치로 이동하면 즉시 내림
                next.isRobotOn = false;
            }
        }
    }

내리는 위치에서 로봇 내리기
컨베이어 벨트 회전 후 내리는 위치에 로봇이 있을 경우 내리게 하기 위한 메서드이다.

//  내리는 위치에 로봇 존재시 내리는 메서드
    public static void exitRobot() {
        Belt end = conveyor.get(n - 1);
        if (end.isRobotOn) {
            end.isRobotOn = false;
        }
    }

올리는 위치에 로봇 올리기
컨베이어 벨트 회전 후, 로봇이 이동하고 나서 제일 앞인 올리는 위치에 로봇을 올리는 메서드

    //  올리는 위치에 로봇을 올리는 메서드
    public static void putRobot() {
        Belt start = conveyor.getFirst();
        if (start.durability >= 1) { //  내구도가 1이상이면
            start.isRobotOn = true; //  로봇을 올리고
            start.durability--; //  내구도 감소
            if (start.durability == 0) {    //  내구도를 내린 후 해당 칸의 내구도가 0이라면
                brokenBelt++;   //  내구도 0인 칸 수 증가
            }
        }
    }

코드

package BOJ;

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

public class sol20055_2 {
    static int n, k;
    static LinkedList<Belt> conveyor;
    static int brokenBelt;
    static int step = 0;

    public static void main(String[] args) throws Exception {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer st = new StringTokenizer(br.readLine());

        n = Integer.parseInt(st.nextToken());
        k = Integer.parseInt(st.nextToken());

        conveyor = new LinkedList<>();
        st = new StringTokenizer(br.readLine());
        for (int i = 0; i < 2 * n; i++) {
            int durability = Integer.parseInt(st.nextToken());
            conveyor.add(i, new Belt(false, durability));
        }

        while (brokenBelt < k) {
            step++;
            rotateBelt();
            exitRobot();
            moveRobots();
            putRobot();
        }

        System.out.println(step);
    }

    //  벨트 회전 메서드
    public static void rotateBelt() {
        conveyor.addFirst(conveyor.removeLast());
    }

    //  로봇 이동 메서드
    public static void moveRobots() {
        for (int i = n - 2; i > 0; i--) {
            Belt curr = conveyor.get(i);
            Belt next = conveyor.get(i + 1);
            if (!curr.isRobotOn) {  //  현재 칸에 로봇이 없으면 패스
                continue;
            }
            if (next.isRobotOn || next.durability < 1) {    //  다음 칸에 로봇이 있거나 내구도가 없어도 패스
                continue;
            }

            //  다음 칸으로 이동할 수 있으면
            next.durability--;  //  다음칸 내구도 감소
            next.isRobotOn = true;  //  다음칸으로 로봇 이동
            curr.isRobotOn = false;

            if (next.durability == 0) { //  이동한 칸이 내구도가 0이면
                brokenBelt++;   //  내구도 0인 칸 수 증가
            }

            if (i + 1 == n - 1) {   //  로봇이 내리는 위치로 이동하면 즉시 내림
                next.isRobotOn = false;
            }
        }
    }

    //  내리는 위치에 로봇 존재시 내리는 메서드
    public static void exitRobot() {
        Belt end = conveyor.get(n - 1);
        if (end.isRobotOn) {
            end.isRobotOn = false;
        }
    }

    //  올리는 위치에 로봇을 올리는 메서드
    public static void putRobot() {
        Belt start = conveyor.getFirst();
        if (start.durability >= 1) { //  내구도가 1이상이면
            start.isRobotOn = true; //  로봇을 올리고
            start.durability--; //  내구도 감소
            if (start.durability == 0) {    //  내구도를 내린 후 해당 칸의 내구도가 0이라면
                brokenBelt++;   //  내구도 0인 칸 수 증가
            }
        }
    }


    public static class Belt {
        boolean isRobotOn;
        int durability;

        Belt(boolean isRobotOn, int durability) {
            this.isRobotOn = isRobotOn;
            this.durability = durability;
        }
    }
}
profile
like the water flowing

0개의 댓글