[백준] #14499. 주사위 굴리기

MTTW·2021년 4월 18일
0

Problem Solving

목록 보기
10/11
post-thumbnail

문제는 여기서 확인할 수 있다. BaekJoon #14499. 주사위 굴리기


📌 POINT

주사위를 지도 위에 두고 주어지는 방향대로 굴린다.

  1. 굴러간 칸이 0이면 주사위의 바닥면의 수를 칸에 복사한다.
  2. 굴러간 칸이 0이 아니면 주사위 바닥면으로 복사하고 지도의 칸은 0으로 바꾼다.
  3. 이후 주사위의 윗면을 출력한다.
  4. 지도 밖으로 나가는 명령은 무시한다.

👉 주사위의 위치와 각 면을 모두 확인하는 시뮬레이션 문제
주사위의 각 면과 굴러가는 함수를 어떻게 구현하느냐가 POINT

주의할 점

  • 굴러가는 방향 인덱스가 생각보다 헷갈린다. 주의하기!
  • 칸 숫자 확인하고 조건에 맞게 구현하기. (질문 페이지에 실수하는 사례가 많이 보인다.)

🚀 풀이

READY

  • 움직이는 방향 인덱스를 미리 정의하고, 그에 맞게 이동 배열을 만든다.
    이번에는 인덱스가 1부터라서 mx[], my[]도 1부터 시작되도록 만들었다.
#define EAST 1
#define WEST 2
#define NORTH 3
#define SOUTH 4

int mx[] = {0, 0, 0, -1, 1};
int my[] = {0, 1, -1, 0, 0};

GO

1. 주사위를 어떻게 구현하느냐가 포인트

deque를 쓰려다가 중간에 있는 변수에 접근하는게 문제가 되서 아래 그림과 같은 배열 두 개를 만들어 구조체 안에 묶었다.

vert[]hori[]는 윗면과 바닥면을 공유한다. 인덱스 1이 윗면, 인덱스 3이 바닥면이다. 따라서 굴리고나면 둘을 동기화 시켜줘야한다.
굴릴 때는 남, 북은 vert[]를 이용하고 동,서는 hori[]를 이용한다.

struct dice{
    int x;
    int y;
    int vert[4] = {0, 0, 0, 0};
    int hori[4] = {0, 0, 0, 0};

    dice(int a, int b) : x(a), y(b) {}

    public:
    bool is_valid_move(int n, int m, int dir){...}
    int roll(int dir){...}
    void roll_east(){
        int temp = hori[3];
        for(int i=3; i>0; i--){
            hori[i] = hori[i-1];
        }
        hori[0] = temp;

        vert[1] = hori[1];
        vert[3] = hori[3];
    }
    void roll_north(){
        int temp = vert[0];
        for(int i=0; i<3; i++){
            vert[i] = vert[i+1];
        }
        vert[3] = temp;

        hori[1] = vert[1];
        hori[3] = vert[3];
    }
    void roll_west(){...}
    void roll_south(){...}
};

2. 전체 알고리즘

  • 굴리는 방향을 입력받는다.
  • 이동 위치가 valid한지 확인한다.
    • invalid하다면 무시
    • valid하다면 이동
      • 이동한 방향으로 주사위도 굴린다.
void game_on(int n, int m, int x, int y, int order_num){
    dice player(x, y);
    int order = 0;
    for(int i=0; i<order_num; i++){
        scanf("%d", &order);
        if(player.is_valid_move(n, m, order)){
            int output = player.roll(order);
            printf("%d\n", output);
        }
    }
    return;
}

3. 주사위 굴리는 알고리즘

  • 해당 방향으로 vert, hori 배열 수정
  • 이동한 위치의 숫자 확인
    • 0이면 보드에 주사위 바닥값을 복사
    • 0이 아니면 보드값을 주사위 바닥에 복사, 보드 칸은 0으로
  • 윗면 숫자 리턴
int roll(int dir){
    // 일단 굴리고
    if(dir == EAST) roll_east();
    else if(dir == WEST) roll_west();
    else if(dir == NORTH) roll_north();
    else roll_south();

    // 바닥 숫자 확인
    if(board[x][y] == 0){
        board[x][y] = vert[3];
    }
    else {
        vert[3] = hori[3] = board[x][y];
        board[x][y] = 0;
    }
    // 윗면 숫자 리턴
    return vert[1];
}
profile
개발자가 되고 싶은 맽튜

0개의 댓글