베오
DCode
베오
전체 방문자
오늘
어제
  • 분류 전체보기 (218)
    • 공지사항 (1)
    • 잡설 (1)
    • Programming (33)
      • [C] (1)
      • [Java] (4)
      • [Python] (2)
      • [Android] (2)
      • [Network] (0)
      • [Operation System] (2)
      • [Spring Boot] (22)
      • [Docker] (0)
    • Algorithm (31)
      • 자료구조 (2)
      • 알고리즘 (Java) (14)
      • 알고리즘 (기초) (15)
    • Coding Test (131)
      • BOJ (131)
      • Algospat (0)
    • 이론적인거 (14)
      • 보안 (5)
      • 오류 해결 (2)
      • 디자인 패턴 (5)
      • 네트워크 (1)
      • 기타 (1)
    • 최신기술 (4)
      • 블록체인 (1)
    • [Project] (1)

블로그 메뉴

  • 🐈‍⬛ GitHub
  • 📫 방명록
  • 🔖 태그

공지사항

인기 글

티스토리

hELLO · Designed By 정상우.
베오

DCode

Coding Test/BOJ

[BOJ/JAVA] 20055 컨베이어 벨트 위의 로봇

2022. 11. 7. 12:59

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

 

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

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

www.acmicpc.net

키워드

로봇은 올리는 위치에만 올릴 수 있다.

언제든지 로봇이 내리는 위치에 도달하면 그 즉시 내린다.

로봇은 컨베이어 벨트 위에서 스스로 이동할 수 있다.

로봇을 올리는 위치에 올리거나 로봇이 어떤 칸으로 이동하면 그 칸의 내구도는 즉시 1만큼 감소한다.

  1. 벨트가 각 칸 위에 있는 로봇과 함께 한 칸 회전한다.
  2. 가장 먼저 벨트에 올라간 로봇부터, 벨트가 회전하는 방향으로 한 칸 이동할 수 있다면 이동한다. 만약 이동할 수 없다면 가만히 있는다.
    • 로봇이 이동하기 위해서는 이동하려는 칸에 로봇이 없으며, 그 칸의 내구도가 1 이상 남아 있어야 한다.
  3. 올리는 위치에 있는 칸의 내구도가 0이 아니면 올리는 위치에 로봇을 올린다.
  4. 내구도가 0인 칸의 개수가 K개 이상이라면 과정을 종료한다. 그렇지 않다면 1번으로 돌아간다.

종료되었을 때 몇 번째 단계가 진행 중이었는지 구해보자. 가장 처음 수행되는 단계는 1번째 단계이다.


구현

  • 각 단계를 메소드로 분리하여 구현하면 간단하게 풀린다.
  • 내구도가 0인 컨베이어 칸의 수를 저장하는 변수를 생성한다.
  • 로봇 ArrayList와 컨베이어 벨트 1차원 배열을 생성한다.
    • **로봇 객체**는 현재 **컨베이어 번호**를 가진다.
    • **컨베이어 벨트 객체**는 **현재 위치에 로봇이 있는지**에 대한 정보와 내구도 정보를 가진다.
  1. 벨트를 회전시키는 메소드 구현
    • [i] → [(i+1) % 2N]
    • 로봇 배열도 인덱스를 위와 같이 증가시킨다.
    • 로봇이 내릴 수 있으면 내린다.
  2. 로봇을 한 칸 이동시키는 메소드 구현
    • 로봇 배열의 맨 앞부터 이동할 수 있으면 이동한다.
      • 이동하려는 위치의 컨베이어벨트 내구도를 1감소시킨다.
        • 0이라면 칸의 수를 저장하는 변수 +1을 한다.
    • 로봇이 내릴 수 있으면 내린다.
  3. 로봇을 올리는 메소드 구현
    • [0] 인덱스에 로봇이 없고, 내구도가 1 이상이라면 로봇을 올린다.
      • [0] 위치의 컨베이어 칸의 내구도를 1감소시킨다.
        • 0이라면 칸의 수를 저장하는 변수 +1을 한다.
  4. 내구도가 0인 칸의 갯수 판단하여 종료하는 메소드 구현

코드

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
import java.util.StringTokenizer;
import java.util.function.Predicate;

public class java_20055 {
    static int N, K;

    static Belt beltList[];
    static List<Robot> robotList;

    static int beltCount;

    static class Belt {
        boolean robot;
        int durability;

        public Belt(int durability) {
            this.robot = false;
            this.durability = durability;
        }
    }

    static class Robot {
        int index;

        public Robot() {
            this.index = 0;
        }
    }

    static void beltMove() {
        // 벨트 회전하기
        Belt tmp = beltList[2 * N - 1];
        for (int i = 2 * N - 1; i > 0; i--) {
            beltList[i] = beltList[i - 1];
        }
        beltList[0] = tmp;

        // 로봇도 같이 회전하기
        for (Robot robot : robotList) {
            robot.index = (robot.index + 1) % (2 * N);

            // 로봇의 현재 위치가 N-1 이라면 내리기
            if (robot.index == N - 1) {
                beltList[N - 1].robot = false;
            }
        }

        // 로봇 내리기
        robotList.removeIf(new Predicate<Robot>() {
            @Override
            public boolean test(Robot t) {
                if (t.index == N - 1) {
                    return true;
                }
                return false;
            }
        });
    }

    static void robotMove() {
        // 로봇 이동하기
        for (int i = 0; i < robotList.size(); i++) {
            // 이동할 인덱스
            int moveIndex = (robotList.get(i).index + 1) % (2 * N);

            // 벨트의 내구도가 1 이상 이여야 하며
            if (1 <= beltList[moveIndex].durability) {
                // 그 위치에 로봇이 없어야 한다.
                if (!beltList[moveIndex].robot) {
                    // 현재 위치 로봇 없어짐
                    beltList[robotList.get(i).index].robot = false;

                    // 이동할 위치 로봇 생김
                    beltList[moveIndex].robot = true;
                    // 내구도 감소
                    beltList[moveIndex].durability -= 1;

                    // 로봇의 위치 조정
                    robotList.get(i).index = moveIndex;

                    // 내구도가 0이 된다면.. 0카운트 증가
                    if (beltList[moveIndex].durability == 0) {
                        beltCount++;
                    }

                    // 현재 인덱스가 N-1 이라면.. 로봇 내리기
                    if (moveIndex == N - 1) {
                        beltList[moveIndex].robot = false;
                    }
                }
            }
        }

        // 로봇 내리기
        robotList.removeIf(new Predicate<Robot>() {
            @Override
            public boolean test(Robot t) {
                if (t.index == N - 1) {
                    return true;
                }
                return false;
            }
        });
    }

    public static void loadRobot() {
        // 로봇 올리기
        // 내구도가 1 이상이여야 함
        if (1 <= beltList[0].durability) {
            // 로봇이 없어야 함
            if (!beltList[0].robot) {
                // 로봇 올라감
                beltList[0].robot = true;
                robotList.add(new Robot());

                // 내구도 감소
                beltList[0].durability -= 1;

                // 내구도가 0이 된다면.. 0카운트 증가
                if (beltList[0].durability == 0) {
                    beltCount++;
                }
            }
        }
    }

    public static boolean stopCheck() {
        // 내구도가 0인 칸의 갯수가 K개 이상이면 .. 종료
        if (K <= beltCount) {
            return true;
        }
        return false;
    }

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

        StringTokenizer st = new StringTokenizer(br.readLine());

        N = Integer.parseInt(st.nextToken());
        K = Integer.parseInt(st.nextToken());

        beltList = new Belt[2 * N];

        st = new StringTokenizer(br.readLine());

        // 내구도가 0인 벨트의 수
        beltCount = 0;

        for (int i = 0; i < 2 * N; i++) {
            beltList[i] = new Belt(Integer.parseInt(st.nextToken()));
            if (beltList[i].durability == 0) {
                beltCount++;
            }
        }

        // 로봇 리스트 생성
        robotList = new ArrayList<>();

        int round = 1;

        while (true) {

            beltMove();

            robotMove();

            loadRobot();

            if (stopCheck()) {
                break;
            } else {
                // 단계 증가
                round++;
            }
        }

        System.out.println(round);

        br.close();
    }
}

저작자표시 (새창열림)

'Coding Test > BOJ' 카테고리의 다른 글

[BOJ/JAVA] 11725번: 트리의 부모 찾기  (0) 2022.11.14
[BOJ/JAVA] 11559번: Puyo Puyo  (0) 2022.11.07
[BOJ/JAVA] 14653번: 너의 이름은  (0) 2022.11.07
[BOJ/JAVA] 1063번: 킹  (0) 2022.11.07
[BOJ/JAVA] 20058번: 마법사 상어와 파이어스톰  (0) 2022.11.07
    'Coding Test/BOJ' 카테고리의 다른 글
    • [BOJ/JAVA] 11725번: 트리의 부모 찾기
    • [BOJ/JAVA] 11559번: Puyo Puyo
    • [BOJ/JAVA] 14653번: 너의 이름은
    • [BOJ/JAVA] 1063번: 킹
    베오
    베오

    티스토리툴바