시뮬레이션 문제이다.
주사위가 상하좌우로 굴러갈 때만 잘 고려하면 크게 어려운 건 없었다.
노트에 주사위가 한 칸 굴렀을 때의 숫자가 어떻게 변했는지 하나씩 그려 확인하는 노가다 작업이 필요했다.
주사위 전면도에 임의의 순서를 붙였다. (1, 2, 4, 5, 6, 3) 순서.
1이 상단을 나타내며, 6이 바닥을 나타낸다.
그 후 오른쪽, 왼쪽 위쪽, 아래쪽으로 돌려보며 해당 숫자가 어떤 곳에 위치하는지 관측한 후, 인덱스 변화 정보를 Rotate 배열에 저장하였다.
예를 들어, 오른쪽으로 굴렸다고 했을 때 (1, 2, 4, 5, 6, 3) 의 숫자는 (4, 2, 6, 5, 3, 1) 가 된다.
이때 인덱스 변화 정보는 1->6, 2->2, 3->1, 4->4, 5->3, 6->5 가 된다. (첫 번째 인덱스에 위치하는 숫자가 여섯 번째 인덱스에 위치하게 된다는 뜻)
문제 흐름은 다음과 같다.
#include <iostream>
#include <cstring>
#include <queue>
using namespace std;
int N, M, sx, sy, K;
int map[20][20];
int dice[7];
int dx[] = { 0, 0, 0, -1, 1 };
int dy[] = { 0, 1, -1, 0, 0 };
int Rotate[5][7] = { {0, 0, 0, 0, 0, 0, 0}, {0, 6, 2, 1, 4, 3, 5}, {0, 3, 2, 5, 4, 6, 1}, {0, 2, 5, 3, 1, 4, 6}, {0, 4, 1, 3, 5, 2, 6} };
queue<int> Dir;
void input() {
cin >> N >> M >> sx >> sy >> 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++) {
int d; cin >> d;
Dir.push(d);
}
memset(dice, 0, sizeof(dice));
}
int is_range(int x, int y) {
if (x >= 0 && x < N && y >= 0 && y < M) return true;
return false;
}
void rotate(int dir) {
int ndice[7];
for(int pre_idx = 1; pre_idx <= 6; pre_idx++){ //주사위의 i번 index에 있는 수가
int nxt_idx = Rotate[dir][pre_idx]; // nxt_idx로 이동
ndice[nxt_idx] = dice[pre_idx];
}
for (int i = 1; i <= 6; i ++) {
dice[i] = ndice[i];
}
}
void solve(int x, int y) {
while (!Dir.empty()) {
int dir = Dir.front();
Dir.pop();
int nx = x + dx[dir];
int ny = y + dy[dir];
if (!is_range(nx, ny)) continue; // 바깥으로 이동시키려고 하는 경우, 명령을 무시
x = nx; y = ny;
rotate(dir);
if (map[nx][ny] == 0) {
map[nx][ny] = dice[5]; // floor
}
else {
dice[5] = map[nx][ny];
map[nx][ny] = 0;
}
cout << dice[1] << endl;
}
}
int main() {
input();
solve(sx, sy);
}