✅ 구현
https://www.acmicpc.net/problem/14499
주사위의 전개도로 주사위가 이동할 때마다 주사위 면의 변화를 예상하기 힘드니 정육면체를 그려 이해하기를 추천한다.
주사위의 6면을 배열로 저장하는데 idx에 따라 아래와 같다.
1 : 윗면의 숫자
6 : 아랫면의 숫자
2 : 북쪽면의 숫자
3 : 동쪽면의 숫자
4 : 서쪽면의 숫자
5 : 남쪽면의 숫자
한번 굴러갈 때마다 위,아래,북,동,서,남쪽의 면이 달라지므로 최신화를 해줘야 한다.
#include <iostream>
#include <algorithm>
#include <string>
#include <vector>
#include <queue>
using namespace std;
int N, M, x, y, K, op;
int map[20][20];
int dice[7]; // idx 0 은 의미 없는 값
int tmp[7]; // 주사위 복사용
void print_dice(){
cout << "\n";
for(int j=1;j<=6;j++){
cout << dice[j] << " ";
}
}
int main()
{
ios_base::sync_with_stdio(false);
cin.tie(NULL);
cout.tie(NULL);
cin >> N >> M >> x >> y >> K;
for(int i=0;i<N;i++){
for(int j=0;j<M;j++){
int num;
cin >> num;
map[i][j] = num;
}
}
for(int i=0;i<K;i++){
cin >> op;
if(op == 1) // 동쪽으로 굴리기
{
if(y+1 >= M) continue;
y += 1;
tmp[6] = dice[3];
tmp[2] = dice[2];
tmp[3] = dice[1];
tmp[4] = dice[6];
tmp[5] = dice[5];
tmp[1] = dice[4];
for(int j=1;j<=6;j++){
dice[j] = tmp[j];
}
if(map[x][y] == 0){
map[x][y] = dice[6];
}
else {
dice[6] = map[x][y];
map[x][y] = 0;
}
cout << dice[1] << "\n";
// cout << "\n" << x << " " << y ;
// print_dice();
}
else if(op == 2) // 서쪽으로 굴리기
{
if(y-1 < 0) continue;
y -= 1;
tmp[6] = dice[4];
tmp[2] = dice[2];
tmp[3] = dice[6];
tmp[4] = dice[1];
tmp[5] = dice[5];
tmp[1] = dice[3];
for(int j=1;j<=6;j++){
dice[j] = tmp[j];
}
if(map[x][y] == 0){
map[x][y] = dice[6];
}
else {
dice[6] = map[x][y];
map[x][y] = 0;
}
cout << dice[1] << "\n";
// cout << "\n" << x << " " << y ;
// print_dice();
}
else if(op == 3) // 북쪽으로 굴리기
{
if(x-1 < 0) continue;
x -= 1;
tmp[6] = dice[2];
tmp[2] = dice[1];
tmp[3] = dice[3];
tmp[4] = dice[4];
tmp[5] = dice[6];
tmp[1] = dice[5];
for(int j=1;j<=6;j++){
dice[j] = tmp[j];
}
if(map[x][y] == 0){
map[x][y] = dice[6];
}
else {
dice[6] = map[x][y];
map[x][y] = 0;
}
cout << dice[1] << "\n";
// cout << "\n" << x << " " << y ;
// print_dice();
}
else{ // 남쪽으로 굴리기
if(x+1 >= N) continue;
x += 1;
tmp[6] = dice[5];
tmp[2] = dice[6];
tmp[3] = dice[3];
tmp[4] = dice[4];
tmp[5] = dice[1];
tmp[1] = dice[2];
for(int j=1;j<=6;j++){
dice[j] = tmp[j];
}
if(map[x][y] == 0){
map[x][y] = dice[6];
}
else {
dice[6] = map[x][y];
map[x][y] = 0;
}
cout << dice[1] << "\n";
// cout << "\n" << x << " " << y ;
// print_dice();
}
}
return 0;
}
O(N)
주사위가 이동할 때마다 각면의 숫자가 어떻게 변화하는지 이해하기가 쉽지 않았다.
종이에 직접 경우를 그려가며 굴려보면서 이해했다.
한번 굴러갈 때마다 위,아래,북,동,서,남쪽의 면이 달라지므로 최신화를 해줘야 하는데 이때 tmp 배열로 옮긴 다음에 다시 dice로 옮겼는데 그 이유는 dice에서 본인 dice로 옮기면 뒤에 옮겨야 할 면이 앞에서 바뀌기 때문이다.