Gi-Log

백준(BOJ) 14499 주사위 굴리기 C++ 풀이 본문

알고리즘 BOJ

백준(BOJ) 14499 주사위 굴리기 C++ 풀이

돌잔 2021. 6. 29. 01:26

문제 링크: 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

문제 풀이에 이용된 알고리즘(?): 단순 구현, 시뮬레이션

 

문제를 잘 읽고, 문제에서 시키는 대로만 하면 된다. 시키는 대로 하기 위해서, 각 행위를 코드로 얼마나 잘 "구현"하는 지가 관건인 문제이다.

 

dx, dy 배열을 이용한 좌표 조정법은 굉장히 흔한 방법이므로 잘 숙지해야 하고, 주사위가 굴러가는 동서남북 방향에 따라서 주사위의 앞, 뒤, 위, 아래, 왼쪽, 오른쪽을 잘 관리해주어야 한다.

 

구조체를 이용하여 주사위를 표현하였는데, 사실 이렇게까지 할 필요도 없이 top, bot, right, left, front, back을 전역변수로 선언해서 관리하기만 해도 충분하다.

 

시뮬레이션을 진행함에 있어서, 주사위가 맵 밖으로 굴러가는 지 확인하고, 경우에 따라서 해당 명령을 스킵(continue 이용)하는 것이 필요했다.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
/* BOJ 14499 주사위 굴리기 */
/* 구현, 시뮬레이션 */
#define _CRT_SECURE_NO_WARNINGS
 
#include <iostream>
#include <queue>
#include <vector>
#include <algorithm>
#include <cstring>
#include <string>
#include <string.h>
 
#define endl '\n'
 
using namespace std;
 
typedef long long ll;
 
int n, m, init_x, init_y, k;
vector<int> commands;
int arr[20][20];
int dx[] = { 000-11 };
int dy[] = { 01-100 };
 
typedef struct DICE
{
    int top, bot, right, left, front, back;
    int x, y;
 
    DICE()
    {
        top = 0, bot = 0, left = 0front = 0, back = 0;
        x = init_x, y = init_y;
    }
 
} DICE;
 
bool isInside(int x, int y)
{
    return 0 <= x && x < n && 0 <= y && y < m;
}
 
void rotate_dice(DICE& dice, int com)
{
    if (com == 1// 동쪽으로 굴리기
    {
        int tmp = dice.left;
        dice.left = dice.bot;
        dice.bot = dice.right;
        dice.right = dice.top;
        dice.top = tmp;
    }
    else if (com == 2// 서쪽으록 굴리기
    {
        int tmp = dice.right;
        dice.right = dice.bot;
        dice.bot = dice.left;
        dice.left = dice.top;
        dice.top = tmp;
    }
    else if (com == 3// 북쪽으로 굴리기
    {
        int tmp = dice.back;
        dice.back = dice.top;
        dice.top = dice.front;
        dice.front = dice.bot;
        dice.bot = tmp;
    }
    else // 남쪽으로 굴리기
    {
        int tmp = dice.front;
        dice.front = dice.top;
        dice.top = dice.back;
        dice.back = dice.bot;
        dice.bot = tmp;
    }
}
 
int main()
{
    ios_base::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
 
    freopen("input.txt""r", stdin);
 
    cin >> n >> m >> init_x >> init_y >> k;
    for (int i = 0; i < n; i++// 초기 보드 상태 입력
        for (int j = 0; j < m; j++)
            cin >> arr[i][j];
 
    while (k--)
    {
        int a;
        cin >> a;
        commands.push_back(a);
    }
 
    DICE dice = DICE();
    for (int command : commands)
    {
        // 주사위가 이동할 칸의 좌표 구하기
        int nx = dice.x + dx[command], ny = dice.y + dy[command];
 
        if (!isInside(nx, ny)) // 주사위가 맵 밖으로 굴러가면
            continue// 해당 명령 무시
 
        dice.x = nx, dice.y = ny; // 주사위 이동
        rotate_dice(dice, command);
 
        if (arr[dice.x][dice.y] == 0)
            arr[dice.x][dice.y] = dice.bot;
        else
        {
            dice.bot = arr[dice.x][dice.y];
            arr[dice.x][dice.y] = 0;
        }
 
        cout << dice.top << endl;
    }
    return 0;
}
 
cs

 

Comments