BOJ

[백준 14499번 / java] 주사위 굴리기

syj0522 2024. 6. 30. 16:14

문제

14499번: 주사위 굴리기 (acmicpc.net)

풀이

보자마자 구현 문제였다.

N*M 크기의 행렬에서 초기 위치 x, y에 모든 면이 0으로 된 주사위가 하나 놓인 채 시작된다.

 

dice() : 명령어 '1234'에 따라 각각 주사위를 '동서북남'으로 굴린다.

invade() : 굴린 주사위가 범위에서 벗어나는지 확인한다.

-주사위를 굴린 후-

move() : 주사위의 전개도에 쓰인 숫자를 바꾼다.

change() : 

좌표 값이 0이면 : 주사위의 바닥면에 쓰여있는 수가 좌표에 복사된다.

좌표 값이 0이 아니면 : 좌표값이 주사위의 바닥면에 복사된다. 좌표값은 0이 된다.

모두 동작이 끝났으면 현재 좌표의 위치 X, Y를 바꿔준다.

 

코드

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

public class Main {
    static int[] d = {0, 0, 0, 0, 0, 0}; //주사위 전개도
    static int[][] board;
    static int N, M, X, Y;
    public static void main(String[] args) throws IOException{
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
        StringTokenizer st;

        st = new StringTokenizer(br.readLine());
        N = Integer.parseInt(st.nextToken());
        M = Integer.parseInt(st.nextToken());
        X = Integer.parseInt(st.nextToken());
        Y = Integer.parseInt(st.nextToken());
        int K = Integer.parseInt(st.nextToken());

        board = new int[N][M];
        for(int i=0; i<N; i++){
            st = new StringTokenizer(br.readLine());
            for(int j=0; j<M; j++){
                board[i][j] = Integer.parseInt(st.nextToken());
            }
        }

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

        for(int i=0; i<K; i++){
            int ans = dice(Integer.parseInt(st.nextToken()));
            if(ans != -1){ //행렬 바깥으로 이동시키려고 하는 경우 제외
                sb.append(ans).append("\n");
            }
        }

        bw.write(sb + " ");
        bw.close();
    }
    static int dice(int k){ //명령, 현재 좌표
        int result = 0;
        switch(k){
            case 1:
                if(invade(X, Y+1))
                    return -1;
                result = change(1, X, Y+1);
                Y += 1;
                break;
            case 2:
                if(invade(X, Y-1))
                    return -1;
                result = change(2, X, Y-1);
                Y -= 1;
                break;
            case 3:
                if(invade(X-1, Y))
                    return -1;
                result = change(3, X-1, Y);
                X -= 1;
                break;
            case 4:
                if(invade(X+1, Y))
                    return -1;
                result = change(4, X+1, Y);
                X += 1;
                break;
            default: break;
        }
        return result;
    }
    static boolean invade(int x, int y){ //주사위를 굴렸을 때 범위에서 벗어남
        if(x<0 || x>=N || y<0 || y>=M){
            return true;
        }
        return false;
    }

    static int change(int k, int x, int y){ //좌표값과 주사위값 바꾸기
        move(k);
        if(board[x][y] == 0){
            board[x][y] = d[3];
            return d[1];
        }else{
            d[3] = board[x][y];
            board[x][y] = 0;
            return d[1];
        }
    }
    static void move(int k){ //주사위 굴린 후 전개도 값 변경
        switch(k){
            case 1:
                d = new int[]{d[0], d[4], d[2], d[5], d[3], d[1]};
                break;
            case 2:
                d = new int[]{d[0], d[5], d[2], d[4], d[1], d[3]};
                break;
            case 3:
                d = new int[]{d[1], d[2], d[3], d[0], d[4], d[5]};
                break;
            case 4:
                d = new int[]{d[3], d[0], d[1], d[2], d[4], d[5]};
                break;
        }
    }

}