💡 너비 우선 탐색/그래프 이론/그래프 탐색/구현/시뮬레이션
Memory 2028KB Time 8ms Code Length 4353B
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
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
//입력 : N, M, K 주어짐
//NxM의 맵
//출력 : 이동에서 획득하는 점수의 합 출력
//주사위는 지도 위에 윗 면이 1이고, 동쪽을 바라보는 방향이 3인 상태로 놓여져 있으며, 놓여져 있는 곳의 좌표는(1, 1) 이다.지도의 각 칸에도 정수가 하나씩 있다.가장 처음에 주사위의 이동 방향은 동쪽
// 1. 주사위가 이동 방향으로 한 칸 굴러간다. 만약, 이동 방향에 칸이 없다면, 이동 방향을 반대로 한 다음 한 칸 굴러간다
// 2. 주사위가 도착한 칸 (x, y)에 대한 점수를 획득한다 // BFS로 해당칸과 같은 칸 찾고 다 더함.
// 3. 주사위의 아랫면에 있는 정수 A와 주사위가 있는 칸 (x, y)에 있는 정수 B를 비교해 이동 방향을 결정한다
// A > B인 경우 이동 방향을 90도 시계 방향으로 회전시킨다.
// A < B인 경우 이동 방향을 90도 반시계 방향으로 회전시킨다.
// A = B인 경우 이동 방향에 변화는 없다.
#include<iostream>
#include<cstring>
#include<queue>
using namespace std;
int N, M, K;
int MAP[20][20];
struct loc {
int y, x;
};
loc diceloc = { 0,0 };
int dice[4][3] =
{
{0, 2, 0},
{4, 1, 3},
{0, 5, 0},
{0, 6, 0},
}; // 초기 윗면은 1 아랫면은 6 동쪽은 3 서쪽은 4 아랫면: dice[3][1]
int score = 0;
int dir = 0; // 초기엔 동쪽
int dy[] = { 0,1,0,-1 };
int dx[] = { 1,0,-1,0 };
void dice_move(int dir) {
// 0 1 2 3 동 남 서 북 으로 잡음
if (dir == 0) {
int tmp = dice[3][1];
dice[3][1] = dice[1][2];
dice[1][2] = dice[1][1];
dice[1][1] = dice[1][0];
dice[1][0] = tmp;
}
else if (dir == 2) {
int tmp = dice[3][1];
dice[3][1] = dice[1][0];
dice[1][0] = dice[1][1];
dice[1][1] = dice[1][2];
dice[1][2] = tmp;
}
else if (dir == 1) {
int tmp = dice[0][1];
dice[0][1] = dice[3][1];
dice[3][1] = dice[2][1];
dice[2][1] = dice[1][1];
dice[1][1] = tmp;
}
else if (dir == 3) {
int tmp = dice[0][1];
dice[0][1] = dice[1][1];
dice[1][1] = dice[2][1];
dice[2][1] = dice[3][1];
dice[3][1] = tmp;
}
}
void init() {
cin >> N >> M >> K;
for (int i = 0; i < N; i++) {
for (int j = 0; j < M; j++) {
cin >> MAP[i][j];
}
}
score = 0;
dir = 0;
diceloc = { 0,0 };
}
void getscore(int y, int x) {
int visited[20][20] = {0};
queue<loc> q;
q.push({ y,x });
visited[y][x] = 1;
score += MAP[y][x];
while (!q.empty()) {
loc now = q.front(); q.pop();
for (int i = 0; i < 4; i++) {
int ny = now.y + dy[i];
int nx = now.x + dx[i];
if (ny >= N || nx >= M || ny < 0 || nx < 0)continue;
if (visited[ny][nx] == 1) continue;
if (MAP[y][x] != MAP[ny][nx]) continue;
visited[ny][nx] = 1;
score += MAP[y][x];
q.push({ ny,nx });
}
}
}
void changedir(int y, int x) {
// A(아랫면) > B(주사위 칸)인 경우 이동 방향을 90도 시계 방향으로 회전시킨다.
// A < B인 경우 이동 방향을 90도 반시계 방향으로 회전시킨다.
// A = B인 경우 이동 방향에 변화는 없다.
if (dice[3][1] > MAP[y][x]) {
dir = (dir + 1) % 4;
}
else if (dice[3][1] < MAP[y][x]) {
dir = (dir + 3) % 4;
}
}
void printdice() {
cout << endl;
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 3; j++) {
cout << dice[i][j] << " ";
}
cout << endl;
}
}
void gamestart() {
// 1. 주사위가 이동 방향으로 한 칸 굴러간다. 만약, 이동 방향에 칸이 없다면, 이동 방향을 반대로 한 다음 한 칸 굴러간다
int ny = diceloc.y + dy[dir];
int nx = diceloc.x + dx[dir];
if (ny >= N || nx >= M || ny < 0 || nx < 0) { // 경계를 넘어간다면
if (dir == 0) dir = 2;
else if (dir == 2) dir = 0;
else if (dir == 1) dir = 3;
else if (dir == 3) dir = 1;
ny = diceloc.y + dy[dir];
nx = diceloc.x + dx[dir];
}
dice_move(dir);
// 2. 주사위가 도착한 칸 (x, y)에 대한 점수를 획득한다 // BFS로 해당칸과 같은 칸 찾고 다 더함.
getscore(ny, nx);
// 3. 주사위의 아랫면에 있는 정수 A와 주사위가 있는 칸 (x, y)에 있는 정수 B를 비교해 이동 방향을 결정한다
changedir(ny, nx);
diceloc.y = ny;
diceloc.x = nx;
//printdice();
//cout << score << endl;
//cout << diceloc.y<< "," << diceloc.x << endl;
}
int main() {
init();
for (int i = 0; i < K; i++) {
gamestart();
}
cout << score << endl;
}
이 코드는 NxM 크기의 맵에서 이동하면서 주사위의 윗 면과 아랫 면에 있는 숫자를 비교하여 방향을 결정하고, 각 칸의 숫자를 합산하여 최종적으로 얻는 점수를 출력하는 프로그램이다.
주사위는 초기에 동쪽을 바라보며 (1, 1) 위치에 있고, 이동 방향에 따라 한 칸씩 이동한다. 이동 방향에 칸이 없을 경우 반대 방향으로 이동한다.
주사위가 도착한 칸의 숫자를 점수에 더한다. 이때, 같은 숫자를 갖는 인접한 칸도 모두 더해야 한다.
주사위의 아랫 면과 도착한 칸의 숫자를 비교하여, 숫자에 따라 이동 방향을 조정한다. 주사위의 아랫 면이 더 크면 시계 방향으로, 작으면 반시계 방향으로 회전한다. 같으면 방향을 유지한다.
이러한 과정을 K번 반복한 후, 얻은 점수를 출력한다.