[boj] (g4) 14499 주사위 굴리기

강신현·2022년 5월 5일
0

✅ 구현

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

1. 해결 로직

주사위의 전개도로 주사위가 이동할 때마다 주사위 면의 변화를 예상하기 힘드니 정육면체를 그려 이해하기를 추천한다.

주사위의 6면을 배열로 저장하는데 idx에 따라 아래와 같다.
1 : 윗면의 숫자
6 : 아랫면의 숫자
2 : 북쪽면의 숫자
3 : 동쪽면의 숫자
4 : 서쪽면의 숫자
5 : 남쪽면의 숫자

한번 굴러갈 때마다 위,아래,북,동,서,남쪽의 면이 달라지므로 최신화를 해줘야 한다.

2. 코드

#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;
}

3. 시간 복잡도

O(N)

4. Review

주사위가 이동할 때마다 각면의 숫자가 어떻게 변화하는지 이해하기가 쉽지 않았다.
종이에 직접 경우를 그려가며 굴려보면서 이해했다.
한번 굴러갈 때마다 위,아래,북,동,서,남쪽의 면이 달라지므로 최신화를 해줘야 하는데 이때 tmp 배열로 옮긴 다음에 다시 dice로 옮겼는데 그 이유는 dice에서 본인 dice로 옮기면 뒤에 옮겨야 할 면이 앞에서 바뀌기 때문이다.

profile
땅콩의 모험 (server)

0개의 댓글