코테 노트/백준

백준 14499 주사위 굴리기 C++

화요밍 2021. 7. 21. 22:45
728x90
반응형

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

 

최종 코드

 

GitHub - hwayeon351/BEAKJOON-Algorithms: 백준 알고리즘 소스 코드 모음

백준 알고리즘 소스 코드 모음. Contribute to hwayeon351/BEAKJOON-Algorithms development by creating an account on GitHub.

github.com

//
//  main.cpp
//  BJ14499
//
//  Created by 최화연 on 2022/04/23.
//

#include <iostream>
using namespace std;

int N, M, K;

struct Dice {
    int x;
    int y;
    int side[7] = {0, };
};
Dice dice;

int map[20][20] = {0, };
int dx[5] = {0, 0, 0, -1, 1};
int dy[5] = {0, 1, -1, 0, 0};

bool move_dice(int dir) {
    dice.x += dx[dir];
    dice.y += dy[dir];
    
    if (dice.x < 0 || dice.x >= N || dice.y < 0 || dice.y >= M) {
        dice.x -= dx[dir];
        dice.y -= dy[dir];
        return false;
    }
    
    int temp = dice.side[1];
    switch (dir) {
        case 1:
            dice.side[1] = dice.side[4];
            dice.side[4] = dice.side[6];
            dice.side[6] = dice.side[3];
            dice.side[3] = temp;
            break;
            
        case 2:
            dice.side[1] = dice.side[3];
            dice.side[3] = dice.side[6];
            dice.side[6] = dice.side[4];
            dice.side[4] = temp;
            break;
            
        case 3:
            dice.side[1] = dice.side[5];
            dice.side[5] = dice.side[6];
            dice.side[6] = dice.side[2];
            dice.side[2] = temp;
            break;
            
        case 4:
            dice.side[1] = dice.side[2];
            dice.side[2] = dice.side[6];
            dice.side[6] = dice.side[5];
            dice.side[5] = temp;
            break;
    }
    
    return true;
}

int main(int argc, const char * argv[]) {
    cin >> N >> M >> dice.x >> dice.y >> K;
    for (int i=0; i<N; i++) {
        for (int j=0; j<M; j++) {
            cin >> map[i][j];
        }
    }
    for (int k=0; k<K; k++) {
        int dir;
        cin >> dir;
        if (move_dice(dir)) {
            if (map[dice.x][dice.y] == 0) map[dice.x][dice.y] = dice.side[6];
            else {
                dice.side[6] = map[dice.x][dice.y];
                map[dice.x][dice.y] = 0;
            }
            cout << dice.side[1] << endl;
        }
    }
    return 0;
}

풀이 과정

풀이 시간 34분

#include <iostream>
using namespace std;

int N, M, K;

struct Dice {
    int x;
    int y;
    int side[7] = {0, };
};
Dice dice;

int map[20][20] = {0, };
int dx[5] = {0, 0, 0, -1, 1};
int dy[5] = {0, 1, -1, 0, 0};

bool move_dice(int dir) {
    dice.x += dx[dir];
    dice.y += dy[dir];
    
    if (dice.x < 0 || dice.x >= N || dice.y < 0 || dice.y >= M) {
        dice.x -= dx[dir];
        dice.y -= dy[dir];
        return false;
    }
    
    int temp = dice.side[1];
    switch (dir) {
        case 1:
            dice.side[1] = dice.side[4];
            dice.side[4] = dice.side[6];
            dice.side[6] = dice.side[3];
            dice.side[3] = temp;
            break;
            
        case 2:
            dice.side[1] = dice.side[3];
            dice.side[3] = dice.side[6];
            dice.side[6] = dice.side[4];
            dice.side[4] = temp;
            break;
            
        case 3:
            dice.side[1] = dice.side[5];
            dice.side[5] = dice.side[6];
            dice.side[6] = dice.side[2];
            dice.side[2] = temp;
            break;
            
        case 4:
            dice.side[1] = dice.side[2];
            dice.side[2] = dice.side[6];
            dice.side[6] = dice.side[5];
            dice.side[5] = temp;
            break;
    }
    
    return true;
}

int main(int argc, const char * argv[]) {
    cin >> N >> M >> dice.x >> dice.y >> K;
    for (int i=0; i<N; i++) {
        for (int j=0; j<M; j++) {
            cin >> map[i][j];
        }
    }
    for (int k=0; k<K; k++) {
        int dir;
        cin >> dir;
        if (move_dice(dir)) {
            if (map[dice.x][dice.y] == 0) map[dice.x][dice.y] = dice.side[6];
            else {
                dice.side[6] = map[dice.x][dice.y];
                map[dice.x][dice.y] = 0;
            }
            cout << dice.side[1] << endl;
        }
    }
    return 0;
}

이전 풀이

풀이 시간 1시간

//
//  main.cpp
//  BJ14499
//
//  Created by Hwayeon on 2021/07/21.
//

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

int map[20][20] = {0,};
int N, M, K;
//0-동, 1-서, 2-북, 3-남
int dx[4] = {1, -1, 0, 0};
int dy[4] = {0, 0, -1, 1};

struct dices{
    int x;
    int y;
    //가장 처음에 주사위의 모든 면 nums[i] = 0
    //주사위의 바닥면 -> 5, 주사위의 윗면 -> 2, 주사위의 옆면 -> 0, 1, 3, 4
    int nums[6] = {0,};
};
dices dice;
deque<int> command;

void change_dice(int d){
    switch(d){
        int temp;
        //동쪽으로 굴리는 경우 - 1->2->3->5->1로 값 이동
        case 0:
            temp = dice.nums[5];
            dice.nums[5] = dice.nums[3];
            dice.nums[3] = dice.nums[2];
            dice.nums[2] = dice.nums[1];
            dice.nums[1] = temp;
            break;
        //서쪽으로 굴리는 경우 - 5->3->2->1->5로 값 이동
        case 1:
            temp = dice.nums[1];
            dice.nums[1] = dice.nums[2];
            dice.nums[2] = dice.nums[3];
            dice.nums[3] = dice.nums[5];
            dice.nums[5] = temp;
            break;
        //북쪽으로 굴리는 경우 - 5->4->2->0->5로 값 이동
        case 2:
            temp = dice.nums[0];
            dice.nums[0] = dice.nums[2];
            dice.nums[2] = dice.nums[4];
            dice.nums[4] = dice.nums[5];
            dice.nums[5] = temp;
            break;
        //남쪽으로 굴리는 경우 - 0->2->4->5->0으로 값 이동
        case 3:
            temp = dice.nums[5];
            dice.nums[5] = dice.nums[4];
            dice.nums[4] = dice.nums[2];
            dice.nums[2] = dice.nums[0];
            dice.nums[0] = temp;
            break;
    }
}

void roll_dice(){
    while(!command.empty()){
        int cmd = command.front();
        command.pop_front();
        //명령 방향으로 주사위를 한 칸 이동할 위치
        int nx = dice.x + dx[cmd];
        int ny = dice.y + dy[cmd];
        //이동할 위치가 지도 밖인 경우 명령을 무시한다
        if(nx<0 || nx>M-1 || ny<0 || ny>N-1) continue;
        
        //주사위의 위치 이동
        dice.x = nx;
        dice.y = ny;
        
        //주사위 면 위치 변경
        change_dice(cmd);
		
        //주사위의 바닥면에 쓰여있는 수가 0인 경우
        if(map[ny][nx] == 0){
        	//주사위의 바닥면에 쓰여있는 수가 칸에 복사된다
            map[ny][nx] = dice.nums[5];
        }
        //주사위의 바닥면(5)에 쓰여있는 수가 0이 아닌 경우
        else{
        	//칸에 쓰여있는 수가 주사위의 바닥면(5)으로 복사된다
            dice.nums[5] = map[ny][nx];
            //칸에 쓰여있는 수는 0이 된다
            map[ny][nx] = 0;
        }
        //주사위의 윗면(2)에 쓰여있는 수 출력
        cout << dice.nums[2] << endl;
    }
}


int main(int argc, const char * argv[]) {
    cin >> N >> M >> dice.y >> dice.x >> K;
    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 c;
        cin >> c;
        command.push_back(c-1);
    }
    roll_dice();
    return 0;
}
//시간복잡도 = O(n), 공간복잡도 = O(n)
728x90
반응형

'코테 노트 > 백준' 카테고리의 다른 글

백준 15683 감시 C++  (0) 2021.08.03
백준 14500 테트로미노 C++  (0) 2021.07.22
백준 3190 뱀 C++  (0) 2021.07.19
백준 21680 상어 초등학교 C++  (0) 2021.07.15
백준 20055 컨베이어 벨트 위의 로봇 C++  (0) 2021.07.13