현생/백준 온라인 저지

[백준 14499][구현] 주사위 굴리기

푸더기 2024. 8. 29. 15:20
반응형

문제 내용

문제 링크

 

우리가 아는 그 주사위가 있다. 또, (N*M)의 지도가 있다.

 

주사위의 초기 숫자는 모두 0이며, 놓여진 위치는 x,y로 주어진다.

 

규칙은 다음과 같다.

  • 주사위가 이동할 때, 이동한 (지도의) 칸이 0이라면 주사위 바닥면에 쓰여 있는 수가 칸에 복사된다.
  • 0이 아니라면 칸에 쓰여있는 수가 주사위의 바닥면으로 옮겨진다. (칸은 0이 된다)
  • 주사위는 지도 바깥으로 이동할 수 없다. (즉 바깥으로 이동하는 명령은 무시한다.)

주사위의 초기 좌표, 지도가 주어졌을 때 각 명령에 대해, 명령대로 이동한 다음 주사위 윗 면의 수를 출력한다.

 

 

문제 풀이

역시나 삼성 코딩테스트 기출 문제인 만큼 구현에 집중하자.

 

본인은 주사위의 인덱스에 집중했다. 

/*
   초기값     인덱스
 * X 1 X    X 0 X
 * 4 5 3    1 2 3
 * X 6 X    X 4 X
 * X 2 X    X 5 X
 *
 * 0번 : top
 * 4번 : bottom
 */
 int dice_map[6] = {1, 4, 5, 3, 6, 2}, dice_num[7] = {0, 0, 0, 0, 0, 0, 0};

주사위가 굴러갈 때마다 dice_map이 알맞게 변한다. 초기값이라 되어있는 그림과 인덱스라 되어있는 그림은 모두 dice_map을 표현한 그림이다. dice_map의 각 인덱스의 값은 dice_num과 매칭된다. 예를 들어, 주사위의 아랫면의 값이 필요하다면 dice_num[dice_map[4]]와 같은 꼴로 구할 수 있다.

 

주사위를 어떻게 굴릴지는 직접 종이에 그려서 구해보자.

 

 

코드

#include <iostream>
using namespace std;

int n, m, x, y, k, arr[20][20];
int dir[5][2] = {{}, {0, 1}, {0, -1}, {-1, 0}, {1, 0}};

/*
   초기값     인덱스
 * X 1 X    X 0 X
 * 4 5 3    1 2 3
 * X 6 X    X 4 X
 * X 2 X    X 5 X
 *
 * 0번 : top
 * 4번 : bottom
 */
int dice_map[6] = {1, 4, 5, 3, 6, 2}, dice_num[7] = {0, 0, 0, 0, 0, 0, 0};

void go_left()
{
    int tmp_map[6] = {dice_map[0], dice_map[1], dice_map[2], dice_map[3], dice_map[4], dice_map[5]};
    dice_map[0] = tmp_map[3];
    dice_map[1] = tmp_map[0];
    dice_map[3] = tmp_map[4];
    dice_map[4] = tmp_map[1];
}

void go_right()
{
    int tmp_map[6] = {dice_map[0], dice_map[1], dice_map[2], dice_map[3], dice_map[4], dice_map[5]};
    dice_map[0] = tmp_map[1];
    dice_map[3] = tmp_map[0];
    dice_map[4] = tmp_map[3];
    dice_map[1] = tmp_map[4];
}

void go_up()
{
    int tmp_map[6] = {dice_map[0], dice_map[1], dice_map[2], dice_map[3], dice_map[4], dice_map[5]};
    dice_map[0] = tmp_map[2];
    dice_map[5] = tmp_map[0];
    dice_map[4] = tmp_map[5];
    dice_map[2] = tmp_map[4];
}

void go_down()
{
    int tmp_map[6] = {dice_map[0], dice_map[1], dice_map[2], dice_map[3], dice_map[4], dice_map[5]};
    dice_map[0] = tmp_map[5];
    dice_map[2] = tmp_map[0];
    dice_map[4] = tmp_map[2];
    dice_map[5] = tmp_map[4];
}

void move_dice(int cmd)
{

    // 갈 수 있는지 확인
    int dx = x + dir[cmd][0], dy = y + dir[cmd][1];
    if (dx < 0 || dy < 0 || dx >= n || dy >= m)
    {
        return;
    }

    // 주사위 위치 갱신
    x = dx;
    y = dy;

    // 주사위 인덱스 갱신
    if (cmd == 1)
        go_right();
    else if (cmd == 2)
        go_left();
    else if (cmd == 3)
        go_up();
    else
        go_down();

    if (arr[x][y] > 0)
    {
        dice_num[dice_map[4]] = arr[x][y];
        arr[x][y] = 0;
    }
    else
    {
        arr[x][y] = dice_num[dice_map[4]];
    }

    cout << dice_num[dice_map[0]] << '\n';
}

int main()
{
    cin.tie(0)->sync_with_stdio(0);
    cin >> n >> m >> x >> y >> k;
    for (int i = 0; i < n; i++)
    {
        for (int j = 0; j < m; j++)
        {
            cin >> arr[i][j];
        }
    }
    while (k--)
    {
        int cmd;
        cin >> cmd;
        move_dice(cmd);
    }
}
반응형