• 백준 14499번 주사위 굴리기 :: 마이구미
    알고리즘 풀이/수학 2017. 10. 29. 16:35
    반응형

    이 글은 백준 알고리즘 문제 14999번 "주사위 굴리기" 를 풀이한다.

    삼성 SW 역량 테스트의 기출 문제이다.

    특정한 알고리즘을 요구하지 않고, 단순히 문제의 이해를 통한 구현이다.

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


    크기가 N×M인 지도가 존재한다. 지도의 오른쪽은 동쪽, 위쪽은 북쪽이다. 이 지도의 위에 주사위가 하나 놓여져 있으며, 주사위의 전개도는 아래와 같다. 지도의 좌표는 (r, c)로 나타내며, r는 북쪽으로부터 떨어진 칸의 개수, c는 서쪽으로부터 떨어진 칸의 개수이다. 

      2
    4 1 3
      5
      6

    주사위는 지도 위에 윗 면이 1이고, 동쪽을 바라보는 방향이 3인 상태로 놓여져 있으며, 놓여져 있는 곳의 좌표는 (x, y) 이다. 가장 처음에 주사위에는 모든 면에 0이 적혀져 있다.

    지도의 각 칸에는 정수가 하나씩 쓰여져 있다. 주사위를 굴렸을 때, 이동한 칸에 써 있는 수가 0이면, 주사위의 바닥면에 써 있는 수가 칸에 복사된다. 0이 아닌 경우에는 칸에 써 있는 수가 주사위의 바닥면으로 복사되며, 칸에 써 있는 수는 0이 된다.

    주사위를 놓은 곳의 좌표와 이동시키는 명령이 주어졌을 때, 주사위가 이동했을 때 마다 상단에 써 있는 값을 구하는 프로그램을 작성하시오.

    주사위는 지도의 바깥으로 이동시킬 수 없다. 만약 바깥으로 이동시키려고 하는 경우에는 해당 명령을 무시해야 하며, 출력도 하면 안된다.


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


    문제를 이해하는 데 시간이 조금 걸리는 문제이다.

    문제만 이해한다면, 구현은 크게 어렵지 않다.

    문제 이해를 통한 구현 문제이기 때문에, 약간 노가다 느낌이 있을 수 있는 문제가 된다.


    문제에서 명시한 주사위의 구조를 정확히 이해해야한다.

    1이 윗면, 6이 밑면이라고 보면 된다.

    주사위를 각 방향으로 굴릴 때, 각 주사위의 면이 가르키는 방향이 다르게 된다는 점을 인지해야한다.

    이 부분은 아래 코드에서 changeDice 함수를 나타낸다.


    주사위의 변화만 이해한다면, 문제는 쉽게 구현하여 해결할 수 있다.

    Github - https://github.com/hotehrud/acmicpc/tree/master/math


    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    static int[] dice = new int[7];
    static int[][] map = new int[20][20];
    static int[] dx = { 1-10}; // 동쪽은 1, 서쪽은 2, 북쪽은 3, 남쪽은 4
    static int[] dy = { 00-1};
    static StringBuilder sb = new StringBuilder();
     
    private void solve() {
        int n = sc.nextInt();
        int m = sc.nextInt();
        int y = sc.nextInt();
        int x = sc.nextInt();
        int k = sc.nextInt();
     
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < m; j++) {
                map[i][j] = sc.nextInt();
            }
        }
     
        for (int i = 0; i < k; i++) {
            int d = sc.nextInt();
            int nx = dx[d - 1+ x;
            int ny = dy[d - 1+ y;
     
            if (<= nx && nx < m && <= ny && ny < n) {
                changeDice(d);
     
                if (map[ny][nx] == 0) {
                    map[ny][nx] = dice[6];
                } else {
                    dice[6= map[ny][nx];
                    map[ny][nx] = 0;
                }
     
                x = nx;
                y = ny;
                sb.append(dice[1+ "\n");
            }
        }
        System.out.println(sb.toString());
    }
     
    public static void changeDice(int d) {
        int[] temp = dice.clone();
        // 6 밑면, 1 윗면
        // 동쪽은 1, 서쪽은 2, 북쪽은 3, 남쪽은 4
        if (d == 1) {
            dice[1= temp[4];
            dice[3= temp[1];
            dice[4= temp[6];
            dice[6= temp[3];
        } else if (d == 2) {
            dice[1= temp[3];
            dice[3= temp[6];
            dice[4= temp[1];
            dice[6= temp[4];
        } else if (d == 3) {
            dice[1= temp[5];
            dice[2= temp[1];
            dice[5= temp[6];
            dice[6= temp[2];
        } else {
            dice[1= temp[2];
            dice[2= temp[6];
            dice[5= temp[1];
            dice[6= temp[5];
        }
    }
    cs


    반응형

    댓글

Designed by Tistory.