본문 바로가기
Algorithm

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

by Ray 2021. 12. 16.

문제 링크 : https://www.acmicpc.net/problem/14499

 

14499번: 주사위 굴리기

첫째 줄에 지도의 세로 크기 N, 가로 크기 M (1 ≤ N, M ≤ 20), 주사위를 놓은 곳의 좌표 x, y(0 ≤ x ≤ N-1, 0 ≤ y ≤ M-1), 그리고 명령의 개수 K (1 ≤ K ≤ 1,000)가 주어진다. 둘째 줄부터 N개의 줄에 지

www.acmicpc.net

 

 

문제 이해 : 

  • 지도 위에서, 주사위를 공처럼 굴리는 것을 상상
  • 한 칸 굴렸을 때, 밑면의 숫자는 변하고, 윗면은 출력
  • 주사위가 굴러갈 때, 어떻게 변하는 지 확인!!

접근 과정 : 

  • 굴러가는 방향에 따라, 주사위의 변화를 확인했고 이를 어떻게 반영할지 고민!!
  • 첫번째 아이디어 
    • 주사위를 한 칸 굴리면 방향에 따라 한 칸씩 이동하니 이를 리스트로 담아서 저장하자!!
    • 주사위의 가로와 세로를 저장할 리스트를 생성하고, 이를 한 칸씩 이동시켜서 굴리기를 반영
  • 두번째 아이디어
    • 주사위 배열을 두고, 방향에 따라 변하는 4개의 면을 즉시 반영

 

소스 코드 및 결과 :

 

/* 
    주사위 굴리기
    
    ** 주사위의 가로와 세로를 따로 기억하면서 굴리기!
*/

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

public class BOJ14499_copy {

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

        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer st = new StringTokenizer(br.readLine());

        int N = Integer.parseInt(st.nextToken());
        int M = Integer.parseInt(st.nextToken());
        int x = Integer.parseInt(st.nextToken());
        int y = Integer.parseInt(st.nextToken());
        int K = Integer.parseInt(st.nextToken());

        int[][] map = new int[N][M];
        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());
            }
        }

        List<Integer> horizontalDice = new ArrayList<>();
        List<Integer> verticalDice = new ArrayList<>();
        int[] dice = new int[7];

        horizontalDice.add(4);
        horizontalDice.add(1);
        horizontalDice.add(3);
        horizontalDice.add(6);

        verticalDice.add(1);
        verticalDice.add(5);
        verticalDice.add(6);
        verticalDice.add(2);

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

        while (K-- > 0) {
            int k = Integer.parseInt(st.nextToken());

            int nx = x + dx[k];
            int ny = y + dy[k];

            if (nx < 0 || nx >= N || ny < 0 || ny >= M) {
                continue;
            }

            switch (k) {
                case 1:

                    y++;
                    verticalDice.set(0, horizontalDice.get(2));
                    verticalDice.set(2, horizontalDice.get(0));

                    horizontalDice.add(horizontalDice.get(0));
                    horizontalDice.remove(0);

                    break;

                case 2:

                    y--;
                    verticalDice.set(0, horizontalDice.get(0));
                    verticalDice.set(2, horizontalDice.get(2));

                    horizontalDice.add(0, horizontalDice.get(3));
                    horizontalDice.remove(4);

                    break;
                case 3:

                    x--;

                    horizontalDice.set(1, verticalDice.get(3));
                    horizontalDice.set(3, verticalDice.get(1));

                    verticalDice.add(0, verticalDice.get(3));
                    verticalDice.remove(4);

                    break;
                case 4:

                    x++;

                    horizontalDice.set(1, verticalDice.get(1));
                    horizontalDice.set(3, verticalDice.get(3));

                    verticalDice.add(verticalDice.get(0));
                    verticalDice.remove(0);

                    break;
            }

            if (map[x][y] == 0) {
                map[x][y] = dice[verticalDice.get(0)];
            } else {
                dice[verticalDice.get(0)] = map[x][y];
                map[x][y] = 0;
            }

            sb.append(dice[horizontalDice.get(3)] + "\n");
        }

        System.out.println(sb.toString().trim());

    }

    static int[] dx = { 0, 0, 0, -1, 1 };
    static int[] dy = { 0, 1, -1, 0, 0 };
}

 

 

 

package BOJ;

/* 
    주사위 굴리기
	
    ** 주사위 배열에 이동을 즉시 반영하면서 굴리기
*/

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

public class BOJ14499 {

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

        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer st = new StringTokenizer(br.readLine());

        int N = Integer.parseInt(st.nextToken());
        int M = Integer.parseInt(st.nextToken());
        int x = Integer.parseInt(st.nextToken());
        int y = Integer.parseInt(st.nextToken());
        int K = Integer.parseInt(st.nextToken());

        int[][] map = new int[N][M];
        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());
            }
        }

        int[] dice = new int[7];

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

        while (K-- > 0) {
            int k = Integer.parseInt(st.nextToken());

            int nx = x + dx[k];
            int ny = y + dy[k];

            if (nx < 0 || nx >= N || ny < 0 || ny >= M) {
                continue;
            }

            int temp;

            switch (k) {
                case 1:

                    y++;

                    temp = dice[4];
                    dice[4] = dice[1];
                    dice[1] = dice[3];
                    dice[3] = dice[6];
                    dice[6] = temp;

                    break;

                case 2:

                    y--;

                    temp = dice[3];
                    dice[3] = dice[1];
                    dice[1] = dice[4];
                    dice[4] = dice[6];
                    dice[6] = temp;

                    break;
                case 3:

                    x--;

                    temp = dice[1];
                    dice[1] = dice[2];
                    dice[2] = dice[6];
                    dice[6] = dice[5];
                    dice[5] = temp;

                    break;
                case 4:

                    x++;

                    temp = dice[1];
                    dice[1] = dice[5];
                    dice[5] = dice[6];
                    dice[6] = dice[2];
                    dice[2] = temp;

                    break;
            }

            if (map[x][y] == 0) {
                map[x][y] = dice[1];
            } else {
                dice[1] = map[x][y];
                map[x][y] = 0;
            }

            sb.append(dice[6] + "\n");
        }

        System.out.println(sb.toString().trim());

    }

    static int[] dx = { 0, 0, 0, -1, 1 };
    static int[] dy = { 0, 1, -1, 0, 0 };
}

 

 

P.S

주사위를 굴릴 때, 한 칸씩 땡겨지거나 미뤄지는 것을 고려해서 리스트를 활용하려고 했다.

그러나 상하로 굴리던, 좌우로 굴리던 두 방향 모두 반영해야하더라..ㅜㅜ

다 해놓고 보니, 그냥 주사위 배열에 즉시 반영하면서 굴려도 될 것 같았다.

사실, 주사위의 변화 파악만 하면 구현은 크게 차이가 없을 것 같다.