BOJ

[백준] 14499번 주사위 굴리기 - C++

시뮬레이션, 구현

Posted by dongjune on November 9, 2020

문제

14499번 주사위 굴리기

풀이

우선 주사위 각면의 숫자를 저장하는 크기 7의 dice 벡터를 만든다. 인덱스 번호를 맞추기 위해 크기를 7로 할당했다.

1
vector<int> dice(7); // index 1 윗면, 2 북쪽면, 3 동쪽면, 4 서쪽면, 5 남쪽면, 6 아랫면

index 1은 윗면, 2 북쪽면, 3 동쪽면, 4 서쪽면, 5 남쪽면, 6 아랫면을 뜻한다. 주사위1

초기의 주사위 벡터는 {0,1,2,3,4,5,6} 의 값을 갖게 된다. 이 상태에서 4 방향으로 굴렸을 때 값을 확인해보자.

  • 동쪽으로 굴리면 -> {0, 4, 2, 1, 6, 5, 3} ( 위 4, 북 2, 동 1, 서 6, 남 5, 아래 3 )
  • 서쪽으로 굴리면 -> {0, 3, 2, 6, 1, 5, 4}
  • 북쪽으로 굴리면 -> {0, 5, 1, 3, 4, 6, 2}
  • 남쪽으로 굴리면 -> {0, 2, 6, 3, 4, 1, 5}

이런 식으로 굴릴 때 인덱스의 위치만 변경해주면 굴릴 때 마다의 주사위 상태를 구현할 수 있다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
// 동쪽으로 굴리기
void rollEast()
{
    dice = {0, dice[4], dice[2], dice[1], dice[6], dice[5], dice[3]};
}

// 서쪽으로 굴리기
void rollWest()
{
    dice = {0, dice[3], dice[2], dice[6], dice[1], dice[5], dice[4]};
}

// 북쪽으로 굴리기
void rollNorth()
{
    dice = {0, dice[5], dice[1], dice[3], dice[4], dice[6], dice[2]};
}

// 남쪽으로 굴리기
void rollSouth()
{
    dice = {0, dice[2], dice[6], dice[3], dice[4], dice[1], dice[5]};
}

이제 소스 코드의 주석을 통해 자세히 살펴보자.

소스 코드

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
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
#include <iostream>
#include <vector>

using namespace std;

int n, m, y, x, k;
int map[21][21];
int order[1001];
vector<int> dice(7); // index 1 윗면, 2 북쪽면, 3 동쪽면, 4 서쪽면, 5 남쪽면, 6 아랫면

// 1 동쪽, 2 서쪽, 3 북쪽, 4 남쪽
int dy[5] = {0, 0, 0, -1, 1};
int dx[5] = {0, 1, -1, 0, 0};

// 입력 
void input()
{
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    cout.tie(NULL);

    cin >> n >> m >> y >> x >> k;

    for (int i = 0; i < n; i++)
    {
        for (int j = 0; j < m; j++)
        {
            cin >> map[i][j];
        }
    }

    for (int i = 0; i < k; i++)
    {
        cin >> order[i];
    }
}

// 동쪽으로 굴리기
void rollEast()
{
    dice = {0, dice[4], dice[2], dice[1], dice[6], dice[5], dice[3]};
}

// 서쪽으로 굴리기
void rollWest()
{
    dice = {0, dice[3], dice[2], dice[6], dice[1], dice[5], dice[4]};
}

// 북쪽으로 굴리기
void rollNorth()
{
    dice = {0, dice[5], dice[1], dice[3], dice[4], dice[6], dice[2]};
}

// 남쪽으로 굴리기
void rollSouth()
{
    dice = {0, dice[2], dice[6], dice[3], dice[4], dice[1], dice[5]};
}

// order에 따라 주사위 굴리기
void roll(int order)
{
    switch (order)
    {
    case 1:
        rollEast();
        break;
    case 2:
        rollWest();
        break;
    case 3:
        rollNorth();
        break;
    case 4:
        rollSouth();
        break;
    default:
        break;
    }
}

void solve()
{
    for (int i = 0; i < k; i++)
    {
        int my = dy[order[i]];
        int mx = dx[order[i]];
        if (y + my >= n || y + my < 0 || x + mx >= m || x + mx < 0)
            continue;
        // 주사위 위치하는 칸 이동
        y += my;
        x += mx;
        // 명령에 따라 주사위 굴리기
        roll(order[i]);

        cout << dice[1] << '\n'; // 윗면 출력

        // 도착한 보드 칸이 0 이라면
        if (map[y][x] == 0)
            map[y][x] = dice[6]; // 주사위 아랫면 숫자를 위치한 칸에 복사
        else
        {
            dice[6] = map[y][x];
            map[y][x] = 0;
        }
    }
}

int main()
{
    input();
    solve();

    return 0;
}