문제 출처

1. 문제설명


  • N*M 크기의 지도에 주사위를 굴리려고 한다.
    • 지도의 각 칸에는 정수가 하나씩 쓰여져 있다.
  • 주사위의 전개도는 다음과 같다.

      2
    4 1 3
      5
      6
    
  • 주사위의 윗면은 위 주석에서 1이고, 동쪽을 바라보는 방향이 3인 상태이다.
  • 가장 처음 주사위에는 0으로 채워져있다.
  • 주사위 굴릴 때 규칙
    • 이동한 칸에 쓰여 있는 수가 0이면, 주사위의 바닥면에 쓰여 있는 수 칸에 복사
    • 0이 아닌 경우에는 칸에 쓰여 있는 수가 주사위의 바닥면으로 복사되며, 칸에 쓰여 있는 수는 0이 된다.
  • 주사위를 놓은 곳의 좌표와 이동시키는 명령이 주어졌을 때 주사위를 이동할 때마다 상단에 쓰여있는 값을 출력하라
  • 주사위는 지도 밖으로 벗어나면 안된다. 이때는 출력도 없다.



2. 알고리즘 설계


  • 주사위 굴리는 것을 제외하면 너무나도 쉬운 문제이다.
  • 본인은 주사위 면이 움직이는 걸 상상하다가 포기하고, 주사위를 종이로 직접 만들어서 시뮬레이션 했다…
    • 4. 소감 사진 참고

  • 각 면에 문제에 나온 면을 적어 주사위를 대충 테이프로 붙여 굴려보면 누구나 코드를 작성할 수 있을 것이다.
    • 아래의 코드에서 void move(int dir)에 구현하였다.



3. 전체 코드


#include <bits/stdc++.h>
using namespace std;
using ull = unsigned long long;

const int dy[] = {0, 0, -1, 1};
const int dx[] = {1, -1, 0, 0};
int n, m, sx, sy, k, board[25][25], cmd;
vector<int> dice(7, 0);

void move(int dir) {
    vector<int> cpy;
    cpy.assign(dice.begin(), dice.end());
    
    if(dir==0) {
        dice[1] = cpy[4];
        dice[3] = cpy[1];
        dice[4] = cpy[6];
        dice[6] = cpy[3];
    }

    else if(dir==1) {
        dice[1] = cpy[3];
        dice[3] = cpy[6];
        dice[4] = cpy[1];
        dice[6] = cpy[4];
    }

    else if(dir==2) {
        dice[1] = cpy[5];
        dice[2] = cpy[1];
        dice[5] = cpy[6];
        dice[6] = cpy[2];
    }

    else {
        dice[1] = cpy[2];
        dice[2] = cpy[6];
        dice[5] = cpy[1];
        dice[6] = cpy[5];
    }
}

bool oom(int y, int x) { return y < 0 || x < 0 || y >= n || x >= m; }

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

    cin >> n >> m >> sy >> sx >> k;
    for(int i=0; i<n; i++)
        for(int j=0; j<m; j++)
        cin >> board[i][j];

    for(int i=0; i<k; i++) {
        cin >> cmd;
        cmd--;

        int ny = sy+dy[cmd];
        int nx = sx+dx[cmd];

        if(oom(ny, nx)) continue;

        move(cmd);
        if(board[ny][nx] == 0)
            board[ny][nx] = dice[6];
        else {
            dice[6] = board[ny][nx];
            board[ny][nx] = 0;
        }

        cout << dice[1] << '\n';
        tie(sy, sx) = {ny, nx};
    }

    return 0;
}



4. 소감


  • 머리로 열심히 상상했지만 전개도만으로는 머리가 뒤죽박죽이었다.
  • 그래서 주사위를 직접 만들어버렸다..
  • 이건 삼성 기출문제인데, 실제 시험장에서도 이렇게 뚝딱뚝딱 만들 상상을 하니 웃겼다..ㅋㅋ
  • 알고리즘 단톡방에 나의 문제 풀이 방법을 공유한 후기