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