[C++]백준 13460번 구슬 탈출2
[C++]백준 13460번 구슬 탈출2
📌문제 링크
https://www.acmicpc.net/problem/13460
📌문제 설명
기본적인 4방향을 탐색하는 bfs문제의 응용 버전이다. 빨간 구슬과 파란 구슬을 동시에 4방향으로 이동시키며 빨간 구슬만 구멍에 빠뜨리는 최단 경로를 BFS로 탐색한다. 방문 상태를 4차원 배열로 관리하고, 각 이동마다 구슬의 위치를 조정하며, 10회 이내에 목표를 달성하지 못하면 -1을 반환한다. 구슬이 겹치는 경우 더 늦게 이동한 구슬의 위치를 조정하는 로직으로 복잡한 시뮬레이션을 해결한다.
📌코드
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
#include <iostream>
#include <queue>
#include <tuple>
#include <cstring>
using namespace std;
const int MAX = 10;
char board[MAX][MAX];
bool visited[MAX][MAX][MAX][MAX];
int N, M;
// 상, 하, 좌, 우 방향
int dx[4] = {-1, 1, 0, 0};
int dy[4] = {0, 0, -1, 1};
// 구슬 위치와 이동 횟수를 저장하는 구조체
struct State {
int rx, ry, bx, by, cnt;
};
// 구슬을 특정 방향으로 이동시키는 함수
pair<bool, pair<int, int>> move(int x, int y, int dx, int dy) {
int nx = x, ny = y;
bool hole = false;
while (board[nx + dx][ny + dy] != '#') {
nx += dx;
ny += dy;
if (board[nx][ny] == 'O') {
hole = true;
break;
}
}
return {hole, {nx, ny}};
}
int bfs(int rx, int ry, int bx, int by) {
queue<State> q;
q.push({rx, ry, bx, by, 0});
visited[rx][ry][bx][by] = true;
while (!q.empty()) {
auto [rx, ry, bx, by, cnt] = q.front();
q.pop();
// 10번 초과하면 실패
if (cnt >= 10) return -1;
for (int dir = 0; dir < 4; dir++) {
auto [rHole, redPos] = move(rx, ry, dx[dir], dy[dir]);
auto [bHole, bluePos] = move(bx, by, dx[dir], dy[dir]);
int nrx = redPos.first, nry = redPos.second;
int nbx = bluePos.first, nby = bluePos.second;
// 파란 구슬이 구멍에 빠지면 실패
if (bHole) continue;
// 빨간 구슬이 구멍에 빠지면 성공
if (rHole) return cnt + 1;
// 두 구슬이 같은 위치에 있으면 위치 조정
if (nrx == nbx && nry == nby) {
switch (dir) {
case 0: // 상
rx < bx ? nbx++ : nrx++;
break;
case 1: // 하
rx > bx ? nbx-- : nrx--;
break;
case 2: // 좌
ry < by ? nby++ : nry++;
break;
case 3: // 우
ry > by ? nby-- : nry--;
break;
}
}
// 방문하지 않은 상태이면 큐에 추가
if (!visited[nrx][nry][nbx][nby]) {
visited[nrx][nry][nbx][nby] = true;
q.push({nrx, nry, nbx, nby, cnt + 1});
}
}
}
return -1;
}
int main() {
ios_base::sync_with_stdio(false);
cin.tie(nullptr);
cin >> N >> M;
int rx = 0, ry = 0, bx = 0, by = 0;
for (int i = 0; i < N; i++) {
for (int j = 0; j < M; j++) {
cin >> board[i][j];
if (board[i][j] == 'R') {
rx = i;
ry = j;
}
else if (board[i][j] == 'B') {
bx = i;
by = j;
}
}
}
int result = bfs(rx, ry, bx, by);
cout << result << '\n';
return 0;
}
This post is licensed under CC BY 4.0 by the author.