본문 바로가기

ALGORITHM/c&c++ baekjoon

[C++/14499] 주사위 굴리기 - using simulation

14499 주사위 굴리기

https://www.acmicpc.net/problem/14499

 

solution

주사위를 굴리는 방향에 따라 달라질 수 있는 맨 위의 숫자를 출력하는 시뮬레이션/구현 문제이다.

이때 주사위 전개도에 따라서 다음과 같이 크게 2개의 배열로 구분 가능하다.

1. 세로 배열

2. 가로 배열

 

주사위를 굴리는 방향에 따라서 특정 배열만 회전해주면 된다. 

입력이 1, 2 인 경우: 동쪽과 서쪽으로 움직이는 것이기 때문에 가로 배열 회전

입력이 3, 4인 경우: 북쪽과 남쪽으로 움직이는 것이기 때문에 세로 배열 회전

 

이때 중요한 점은 가로 배열과 세로 배열은 값이 공통인 부분이 존재한다는 것이다. (위쪽과 아래쪽)

따라서 이 부분은 특정 배열을 회전할 때마다 다른 하나의 배열에 값을 복사해준다.

 

전체 코드

 

#include <iostream>
#include <vector>
using namespace std;

int N, M, X, Y, K;
int map[20][20];
int dx[4] = {0, 0, -1, 1};		// 주사위 x 방향
int dy[4] = {1, -1, 0, 0};		// 주사위 y 방향
int diceRow[4] = {0, 0, 0, 0};	// 주사위 가로 배열 {뒤, 아래, 앞, 위}
int diceCol[4] = {0, 0, 0, 0};	// 주사위 세로 배열 {왼쪽, 아래, 오른쪽, 위}

// 가로 배열 회전 시 공통 부분 복사
void makeColCopy(int tempX, int tempY) {
	// 아래와 오른쪽의 값은 공통임
    diceRow[3] = diceCol[3];
    diceRow[1] = diceCol[1];
    
    if (map[tempX][tempY] == 0) {
        map[tempX][tempY] = diceRow[1];
    }
    else {
        diceRow[1] = diceCol[1] = map[tempX][tempY];
        map[tempX][tempY] = 0;
    }
}

// 세로 배열 회전 시 공통 부분 복사
void makeRowCopy(int tempX, int tempY) {
	// 아래와 오른쪽의 값은 공통임
    diceCol[3] = diceRow[3];
    diceCol[1] = diceRow[1];
    
    if (map[tempX][tempY] == 0) {
        map[tempX][tempY] = diceCol[1];
    }
    else {
        diceRow[1] = diceCol[1] = map[tempX][tempY];
        map[tempX][tempY] = 0;
    }
}

int main() {
    cin>>N>>M>>X>>Y>>K;
    
    for(int i = 0;i < N;i++) {
        for(int j = 0;j < M;j++) {
            cin>>map[i][j];
        }
    }
    
    while(K--) {
        int dir;
        cin>>dir;
        
        // 주사위 굴리는 방향의 좌표
        int tempX = X + dx[dir - 1];
        int tempY = Y + dy[dir - 1];
        
        // 주사위를 굴리는 방향이 map을 벗어나지 않고 유효한 값인지 체크
        if (tempX < 0 || tempY < 0 || tempX >= N || tempY >= M) {
            continue;
        }
        
        // 동
        if (dir == 1) {
            int top = diceRow[0];
            for(int i = 0;i <= 2;i++) {
                diceRow[i] = diceRow[i + 1];
            }
            diceRow[3] = top;
            makeRowCopy(tempX, tempY);
        }
        // 서
        else if (dir == 2) {
            int bottom = diceRow[3];
            for(int i = 3;i >= 1;i--) {
                diceRow[i] = diceRow[i - 1];
            }
            diceRow[0] = bottom;
            makeRowCopy(tempX, tempY);
        }
        // 북
        else if (dir == 3) {
            int bottom = diceCol[3];
            for(int i = 3;i >= 1;i--) {
                diceCol[i] = diceCol[i - 1];
            }
            diceCol[0] = bottom;
            makeColCopy(tempX, tempY);
        }
        // 남
        else if (dir == 4) {
            int top = diceCol[0];
            for(int i = 0;i <= 2;i++) {
                diceCol[i] = diceCol[i + 1];
            }
            diceCol[3] = top;
            makeColCopy(tempX, tempY);
        }
        
        // 아래쪽 값 출력
        cout<<diceCol[3]<<"\n";
        
        X = tempX;
        Y = tempY;
    }
}

 

크게 어렵지 않게 풀 수 있으나 주사위 회전에 대해 감을 못 잡는다면 삽질할 수도 있을만한 문제인듯하다.