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

문제 (Gold 5)

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

풀이

문제가 참,, 여러모로 이해하기 어려웠다,,

다른것보다 갑자기 출력하라고 나온 단어인 '단계'가 무엇인지 예제를 몇개 돌려보고야 알았던 것 같다.

여기선 1-4의 루틴을 한 단계라고 하고, 종료되기까지 총 몇번의 단계를 거쳤는지를 구하면 된다.

처음엔 일의 순서로 나와있는 1,2,3,4가 한 단계를 나타내는 줄 알았고,
예제1의 출력이 '2'번 단계, 즉 '가장 먼저 벨트에 올라간 ~' 라는 줄 알았다. 문제에 모호한 점이 너무 많다 💦

문제 자체가 헷갈렸던 것 외에는 보통의 시뮬레이션 문제처럼 하나씩 구현만 하면 된다.

순서

  • Belt라는 내구도와 로봇의 여부를 저장하는 클래스를 만들었다.
    ❗ 로봇은 무조건 한 칸에 하나만 올라갈 수 밖에 없다. 따라서 boolean 타입 선언!
  • [1번 순서] 컨베이어를 배열로 만들어 벨트의 회전은 배열의 회전으로 구현하였다.
    ❗ i = 0 부터 i+1에 값을 복사하는 방식이면, 값이 반복되어 복사된다. 즉, conv[0]의 값으로 모든 배열이 도배된다!
    따라서, 2*N-1부터 i를 줄여나가며 값을 복사하자!
  • [1번 순서] 벨트 회전 후, N-1인덱스의 robot은 무조건 false로 바꾸자. ( 내려가는 곳 )
  • [2번 순서] 가장 먼저 벨트에 올라간 로봇 -> i-1부터 0번까지의 컨베이어 배열 탐색
    ❗ '가장 먼저 올라간'에 속아 따로 순서를 기억하지 말자!
    어차피 N ~ 2N-1까지는 로봇이 무조건 없고, 결국엔 맨 오른쪽 (N-1과 가까운쪽)에 있는 애가 제일 오래된 애다!
  • [2번 순서] 컨베이어 벨트 회전과 마찬가지로 로봇을 이동시키고 N-1인덱스의 robot은 무조건 false로! 

문제 이해도 힘들고, 까다로운 조건이 너무 많았던 지저분한,,문제,,💦

코드

package simulation;

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

public class BOJ_20055_컨베이어벨트위의로봇 {
    static class Belt{
        int power;
        boolean robot;
        public Belt(int power) {
            this.power = power;
            this.robot = false;
        }
    }
    static int N, K;
    static Belt[] conv;
    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());
        conv = new Belt[2*N];
        st = new StringTokenizer(br.readLine());
        for(int i =0 ; i < 2*N ; i++){
            conv[i] = new Belt(Integer.parseInt(st.nextToken()));
        }

        int stage = 1;
        while(true){
            // 1. 회전
            int p = conv[2*N-1].power;
            boolean r = conv[2*N-1].robot;
            for(int i = 2*N-1 ; i > 0 ; i--){
                conv[i].power = conv[i-1].power;
                conv[i].robot = conv[i-1].robot;
            }
            conv[0].power = p;
            conv[0].robot = r;
            conv[N-1].robot = false;

            // 2. 가장 먼저 올라간 로봇부터, 이동
            for(int i = N-1 ; i > 0 ; i--){
                if(!conv[i].robot && conv[i-1].robot && conv[i].power >= 1){
                    conv[i].power --;
                    conv[i].robot = true;
                    conv[i-1].robot = false;
                }
            }
            conv[0].robot = false;
            conv[N-1].robot = false;

            // 3. 올리는 위치에 로봇 올림
            if(conv[0].power != 0){
                conv[0].robot = true;
                conv[0].power --;
            }
            if(!isValid()) break;
            stage++;
        }
        System.out.println(stage);
    }

    private static boolean isValid() {
        int cnt = 0;
        for(int i = 0 ; i < 2*N ; i++){
            if(conv[i].power <= 0) cnt++;
        }
        return cnt < K;
    }
}

제출


특별한 반례 없이 문제만 잘 이해하고 예제만 다 맞았다면 통과 가눙

좋은 웹페이지 즐겨찾기