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

 

14499번: 주사위 굴리기

첫째 줄에 지도의 세로 크기 N, 가로 크기 M (1 ≤ N, M ≤ 20), 주사위를 놓은 곳의 좌표 x y(0 ≤ x ≤ N-1, 0 ≤ y ≤ M-1), 그리고 명령의 개수 K (1 ≤ K ≤ 1,000)가 주어진다. 둘째 줄부터 N개의 줄에 지도

www.acmicpc.net

 

 

풀이

이 문제에서 가장 까다로웠던 것은 주사위가 굴러가는 것이다. 좌, 우로만 움직이거나 상, 하로만 움직인다면 굉장히 쉬운 일이지만 만약 지금 상태에서 상하로 구르는 것과 좌로 한 칸 이동 후에 상하로 구르는 것은 완전 다른 패턴을 가지고 있으므로 표현하는 것이 어렵다. 따라서 주사위가 상,하,좌,우로 굴렀을 때 값의 위치가 어디로 가는 지를 알고 상, 하, 좌, 우로 이동하는 함수 4개를 만들었다. 예시로 다음과 같다. 만약 주사위가 위의 문제와 같이 있고 1이 위에 있다고 가정하자. 주사위를 위로 굴렸을 때 값은 이렇게 바뀐다.

1번 자리 : 5

2번 자리 : 1

3번 자리 : 3

4번 자리 : 4

5번 자리 : 6

6번 자리 : 2

그림 예시

이런 방식으로 상, 하, 좌, 우로 굴렀을 때의 주사위를 나타내는 함수를 만들었다. 그 다음은 어렵지 않다. 문제에서 준 대로 바닥이 0인 경우 주사위의 아래있는 값을 복사하고 0이 아닌 경우 주사위의 면을 갱신하고 바닥을 0으로 만들면 된다.

 

소스 코드

#include <iostream>
#include <cstring>
#include <vector>
#include <deque>

using namespace std;

int board[21][21];

int dice[6] = {0, 0, 0, 0, 0, 0}; //초기 주사위 전개도 순서로 초기화

void up() { //위로 굴렀을 때의 주사위 값 변화
    int tmp[6];
    tmp[0] = dice[4];
    tmp[1] = dice[0];
    tmp[2] = dice[2];
    tmp[3] = dice[3];
    tmp[4] = dice[5];
    tmp[5] = dice[1];
    memcpy(dice, tmp, sizeof(dice));
}

void down() { //아래로 굴렀을 때의 주사위 값 변화
    int tmp[6];
    tmp[0] = dice[1];
    tmp[1] = dice[5];
    tmp[2] = dice[2];
    tmp[3] = dice[3];
    tmp[4] = dice[0];
    tmp[5] = dice[4];
    memcpy(dice, tmp, sizeof(dice));
}

void left() { //왼쪽으로 굴렀을 때의 주사위 값 변화
    int tmp[6];
    tmp[0] = dice[2];
    tmp[1] = dice[1];
    tmp[2] = dice[5];
    tmp[3] = dice[0];
    tmp[4] = dice[4];
    tmp[5] = dice[3];
    memcpy(dice, tmp, sizeof(dice));
}

void right() { //오른쪽으로 굴렀을 때의 주사위 값 변화
    int tmp[6];
    tmp[0] = dice[3];
    tmp[1] = dice[1];
    tmp[2] = dice[0];
    tmp[3] = dice[5];
    tmp[4] = dice[4];
    tmp[5] = dice[2];
    memcpy(dice, tmp, sizeof(dice));
}

int main() {
    int N, M, x, y, K; cin >> N >> M >> x >> y >> K;

    for(int i = 0; i < N; i++) {
        for(int j = 0; j < M; j++) {
            cin >> board[i][j];
        }
    }
    if(board[x][y] == 0) { //바닥이 0인 경우
        board[x][y] = dice[5]; //주사위값 복사
    }
    else { //바닥이 0이 아닌 경우
        dice[5] = board[x][y]; //주사위에 바닥값 복사
        board[x][y] = 0; //바닥은 0으로
    }
    for(int i = 0; i < K; i++) {
        int a; cin >> a;
        switch(a) {
            case 1: //동쪽으로 가는 경우
                if(y + 1 < M) { //벗어나지 않을 때 동작
                    y++;
                    right();
                }
                else continue;
                break;
            case 2: //서쪽으로 가는 경우
                if(y-1 >= 0) {
                    y--;
                    left();
                }
                else continue;
                break;
            case 3: //북쪽으로 가는 경우
                if(x-1 >= 0) {
                    x--;
                    up();
                }
                else continue;
                break;
            case 4: //남쪽으로 가는 경우
                if(x+1 < N) {
                    x++;
                    down();
                }
                else continue;
                break;
        }
        if(board[x][y] == 0) { //바닥이 0인 경우
            board[x][y] = dice[5]; //바닥에 주사위 아래값 복사
        }
        else { //바닥이 1인 경우
            dice[5] = board[x][y]; //주사위 아래에 바닥값 복사
            board[x][y] = 0; //바닥은 0으로
        }
        cout << dice[0] << '\n'; //주사위 위에 있는 값 출력
    }
}

 

 

채점 결과

+ Recent posts