문제/백준

[백준] 14499 주사위 굴리기 - Java

icodesiuuuu 2025. 1. 18. 21:18

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

 

문제 개요

이 문제는 크기가 N×M인 지도 위에서 주사위를 굴리며 주어진 명령에 따라 이동시키고, 이동한 후의 주사위 상태를 업데이트하는 시뮬레이션 문제입니다.
주사위의 전개도는 주어진 상태를 기반으로 동쪽, 서쪽, 북쪽, 남쪽으로 굴릴 때 각 면의 값을 적절히 변경해야 하며, 주사위가 지도 위를 이동할 때 다음 규칙을 따릅니다:

  1. 이동한 칸에 쓰여 있는 값이 0이면 주사위의 바닥면 값을 그 칸에 복사합니다.
  2. 이동한 칸에 값이 0이 아니면, 해당 값을 주사위의 바닥면에 복사하고, 칸의 값은 0으로 변경됩니다.
  3. 주사위가 지도 밖으로 벗어나는 이동 명령은 무시합니다.

 

 

접근 방법

1. 주사위 전개도의 표현

주사위의 전개도를 배열로 표현하여 굴릴 때 각 면의 값을 갱신하는 방식을 사용했습니다.
주사위의 전개도는 아래와 같이 4×3 배열로 나타냅니다

 

  • dice[1][1]은 항상 주사위의 윗면을 나타냅니다.
  • dice[3][1]은 항상 주사위의 바닥면을 나타냅니다

2. 이동 명령 구현

명령에 따라 주사위를 굴리는 함수 east(), west(), north(), south()를 정의했습니다. 각 함수는 아래 단계를 거칩니다:

  • 지도 범위 체크: 명령에 따른 이동이 지도의 범위를 벗어난 경우 무시.
  • 주사위 상태 갱신: 명령 방향에 따라 주사위 전개도의 값을 갱신.
  • 지도 값 처리: 이동한 칸의 값에 따라 주사위와 지도의 값을 교환하거나 복사.
  • 주사위 상단 출력: 갱신 후 dice[1][1] 값을 출력.

3. 주사위 굴리기

  • 동쪽(east())과 서쪽(west()): 주사위 전개도의 가로축 값들을 회전시킵니다.
  • 북쪽(north())과 남쪽(south()): 전개도의 세로축 값을 회전시킵니다.

예를 들어, 동쪽으로 굴릴 때:

  • [1][1](윗면)은 [1][0](왼쪽)으로, [1][0]은 [3][1](바닥)으로, [3][1]은 [1][2](오른쪽)으로 이동합니다.

4. 지도 값 처리

이동한 칸의 값이 0인지 아닌지에 따라 주사위와 지도의 값을 교환하거나 복사합니다:

  • map[r][c] == 0: 주사위 바닥면 값을 map[r][c]에 복사.
  • map[r][c] != 0: map[r][c] 값을 주사위 바닥면에 복사 후, 칸의 값은 0으로 초기화.

5. 전체 시뮬레이션

모든 명령어를 반복하며 위 과정을 수행합니다:

  • 주어진 명령어 순서를 차례로 읽어 명령에 따라 주사위를 굴립니다.
  • 각 이동 후 주사위의 윗면 값을 출력합니다.

 

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;

public class Main {
    static int[][] dice = new int[4][3];
    static int[][] map;
    static int N, M, r, c, cntCmd;
    static int[] cmd;

    public static void main(String[] args) throws IOException {
        init();

        for(int i=0; i<cmd.length; i++) {
            switch (cmd[i]) {
                case 1:
                    east();
                    break;
                case 2:
                    west();
                    break;
                case 3:
                    north();
                    break;
                case 4:
                    south();
                    break;
            }
        }
    }

    public static void check() {
        if(map[r][c] == 0) {
            map[r][c] = dice[3][1];
        } else {
            dice[3][1] = map[r][c];
            map[r][c] = 0;
        }
    }

    public static void east() {
        if(r<0 || c+1<0 || r>=map.length || c+1>=map[0].length) return;
        int tmp = dice[1][1];
        dice[1][1] = dice[1][0];
        dice[1][0] = dice[3][1];
        dice[3][1] = dice[1][2];
        dice[1][2] = tmp;

        c+=1;
        check();
        System.out.println(dice[1][1]);
    }

    public static void west() {
        if(r<0 || c-1<0 || r>=map.length || c-1>=map[0].length) return;

        int tmp = dice[1][1];
        dice[1][1] = dice[1][2];
        dice[1][2] = dice[3][1];
        dice[3][1] = dice[1][0];
        dice[1][0] = tmp;

        c-=1;
        check();
        System.out.println(dice[1][1]);
    }

    public static void north() {
        if(r-1<0 || c<0 || r-1>=map.length || c>=map[0].length) return;

        int tmp = dice[1][1];
        dice[1][1] = dice[2][1];
        dice[2][1] = dice[3][1];
        dice[3][1] = dice[0][1];
        dice[0][1] = tmp;

        r-=1;
        check();
        System.out.println(dice[1][1]);
    }

    public static void south() {
        if(r+1<0 || c<0 || r+1>=map.length || c>=map[0].length) return;

        int tmp = dice[1][1];
        dice[1][1] = dice[0][1];
        dice[0][1] = dice[3][1];
        dice[3][1] = dice[2][1];
        dice[2][1] = tmp;

        r+=1;
        check();
        System.out.println(dice[1][1]);
    }

    public static void init() throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer st = new StringTokenizer(br.readLine());

        N = Integer.parseInt(st.nextToken());
        M = Integer.parseInt(st.nextToken());
        r = Integer.parseInt(st.nextToken());
        c = Integer.parseInt(st.nextToken());
        cntCmd = Integer.parseInt(st.nextToken());

        map = new int[N][M];
        cmd = new int[cntCmd];

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

 

'문제 > 백준' 카테고리의 다른 글

[백준] 14890 경사로 - Java  (1) 2025.01.24
[백준] 14503 로봇 청소기 - Java  (1) 2025.01.19
[백준] 10799 쇠막대기 - Java  (0) 2024.10.31
[백준] 4920 테트리스 게임 - Java  (0) 2024.10.30
[백준] 1654 랜선 자르기 - Java  (2) 2024.10.25