프로그래밍/알고리즘 PS

[C++] BOJ 14499번: 주사위 굴리기

코딩 제이티 2020. 11. 4. 11:46

문제 링크

문제 풀이

문제에 주어진 조건을 그대로 시뮬레이션하는 방식으로 문제를 풀었다. 문제를 풀 때에 "지도의 좌표는 (r, c)로 나타내며, r는 북쪽으로부터 떨어진 칸의 개수, c는 서쪽으로부터 떨어진 칸의 개수이다."라고 적힌 부분을 주의 깊게 읽어야 한다. 필자는 이 부분을 무시하여 처음에 코드를 작성할 때에 x가 들어갈 좌표에 y, y가 들어갈 좌표에 x가 들어가도록 구현하는 문제가 발생하였다.

 

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

코드

#include <iostream>

using namespace std;

#define RIGHT 1
#define LEFT 2
#define DOWN 3
#define UP 4

int N, M;
int x, y;
int K;

int map[30][30]; // index: [yp][xp] / yp: 0 ~ M - 1, xp: 0 ~ N - 1
int order[1001]; // index: 0 ~ K - 1

int diceIdxHeight = 0;
int diceIdxWidth = 0;

int diceHeight[4] = {1, 5, 6, 2};
int diceWidth[4] = {1, 3, 6, 4};

int value[7];

void setDiceBottom()
{
    if (map[y][x] == 0)
    {
        map[y][x] = value[diceWidth[(diceIdxWidth + 2) % 4]];
        return;
    }
    value[diceWidth[(diceIdxWidth + 2) % 4]] = map[y][x];
    map[y][x] = 0;
}

void moveDice(int direction)
{
    int nx = x;
    int ny = y;
    switch (direction)
    {
    case UP:
        ny += 1;
        break;
    case DOWN:
        ny -= 1;
        break;
    case LEFT:
        nx -= 1;
        break;
    case RIGHT:
        nx += 1;
        break;
    }

    if (nx < 0 || ny < 0 || nx >= M || ny >= N)
        return;

    x = nx;
    y = ny;

    switch (direction)
    {
    case UP:
        diceIdxHeight = (diceIdxHeight + 3) % 4;
        diceWidth[diceIdxWidth] = diceHeight[diceIdxHeight];
        diceWidth[(diceIdxWidth + 2) % 4] = diceHeight[(diceIdxHeight + 2) % 4];
        break;
    case DOWN:
        diceIdxHeight = (diceIdxHeight + 1) % 4;
        diceWidth[diceIdxWidth] = diceHeight[diceIdxHeight];
        diceWidth[(diceIdxWidth + 2) % 4] = diceHeight[(diceIdxHeight + 2) % 4];
        break;
    case LEFT:
        diceIdxWidth = (diceIdxWidth + 1) % 4;
        diceHeight[diceIdxHeight] = diceWidth[diceIdxWidth];
        diceHeight[(diceIdxHeight + 2) % 4] = diceWidth[(diceIdxWidth + 2) % 4];
        break;
    case RIGHT:
        diceIdxWidth = (diceIdxWidth + 3) % 4;
        diceHeight[diceIdxHeight] = diceWidth[diceIdxWidth];
        diceHeight[(diceIdxHeight + 2) % 4] = diceWidth[(diceIdxWidth + 2) % 4];
        break;
    }

    setDiceBottom();
    cout << value[diceWidth[diceIdxWidth]] << '\n';
}

int main(void)
{
    cin.tie(nullptr);
    ios::sync_with_stdio(false);

    cin >> N >> M >> y >> x >> K;

    for (int yp = 0; yp < N; yp++)
        for (int xp = 0; xp < M; xp++)
            cin >> map[yp][xp];

    for (int i = 0; i < K; i++)
        cin >> order[i];

    for (int i = 0; i < K; i++)
        moveDice(order[i]);

    return 0;
}