[백준] 14499번 : 주사위 굴리기

김개발·2021년 9월 28일
0

백준

목록 보기
42/75

문제 푼 날짜 : 2021-09-28

문제

문제 링크 : https://www.acmicpc.net/problem/14499

접근 및 풀이

아래처럼 문제에 주어진 주사위 형태에서 힌트를 얻어 쉽게 풀 수 있었다.

주사위를 4x3 배열의 형태로 봤을 때, (1, 1)이 주사위의 상단이고, (3, 1)이 주사위의 하단이라고 생각했다. 배열의 -1 을 제외한 부분이 주사위의 여섯면을 나타내는 것이고, 이를 기준으로 주사위가 동, 서, 남, 북 각각으로 이동했을 때 회전하는 것을 표현해주었다.(코드 내의 rolling함수)
좀 더 이쁘게 구현하는 방법이 있을 것 같지만,, 우선은 이렇게 생각했다..

주사위를 어떻게 나타낼지만 결정하면 주어진 입력대로 주사위를 굴리면서 조건을 따져주면 된다.
주사위를 굴렸을 때, 이동한 바닥면에 맞닿은 주사위의 숫자(주사위 배열 (3, 1)에 해당)와 바닥면의 숫자를 비교해서 어떤 숫자를 복사할지 결정해주었다.

코드

// 백준 14499번 : 주사위 굴리기
#include <iostream>
#include <vector>

using namespace std;

#define EAST 0
#define WEST 1
#define NORTH 2
#define SOUTH 3

int dice[4][3] =
{{ -1, 0, -1 },
 {  0, 0, 0 },
 { -1, 0, -1 },
 { -1, 0, -1 }};

int map[21][21] = { 0, };
int D[4][2] = {{ 0, 1 }, { 0, -1 }, { -1, 0 }, { 1, 0 }};

void rolling(int dir) {
    int top = dice[1][1];
    
    if (dir == EAST) {
        dice[1][1] = dice[1][0];
        dice[1][0] = dice[3][1];
        dice[3][1] = dice[1][2];
        dice[1][2] = top;
    } else if (dir == WEST) {
        dice[1][1] = dice[1][2];
        dice[1][2] = dice[3][1];
        dice[3][1] = dice[1][0];
        dice[1][0] = top;
    } else if (dir == SOUTH) {
        dice[1][1] = dice[0][1];
        dice[0][1] = dice[3][1];
        dice[3][1] = dice[2][1];
        dice[2][1] = top;
    } else if (dir == NORTH) {
        dice[1][1] = dice[2][1];
        dice[2][1] = dice[3][1];
        dice[3][1] = dice[0][1];
        dice[0][1] = top;
    }
}

int main() {
    int N, M, y, x, K;
    cin >> N >> M >> y >> x >> K;
    
    vector<int> moves;
    
    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 m;
        cin >> m;
        moves.push_back(m - 1);
    }
    
    for (int i = 0; i < moves.size(); i++) {
        int move = moves[i];
        int nextY = y + D[move][0];
        int nextX = x + D[move][1];
        
        if (nextY < 0 || nextY >= N || nextX < 0 || nextX >= M) {
            continue;
        }
        rolling(move);
        int top = dice[1][1];
        int bottom = dice[3][1];
        
        cout << top << '\n';
        
        if (map[nextY][nextX] == 0) {
            map[nextY][nextX] = bottom;
        } else {
            dice[3][1] = map[nextY][nextX];
            map[nextY][nextX] = 0;
        }
        y = nextY, x = nextX;
    }
    return 0;
}

결과

피드백

좀 코드가 조잡한 것 같지만, 이런 문제는 빠르게 이해하고 직관적으로 코드를 구현하는 것도 중요한 것 같다.

profile
개발을 잘하고 싶은 사람

0개의 댓글