다차원 배열이 주어졌을 때 Queue를 이용하여 BFS 구현하기 : C++
백준의 문제를 풀다보면 다차원 배열, 즉 여러 개의 칸으로 이루어져 있는 구조가 있고 칸들을 탐색해야 할 때가 있다. 따라서 다차원 배열이 주어졌을 때 queue를 사용하여 BFS를 구현하는 방법에 대해서 알아보겠다. 문제에 맞게 해당 방법을 베이스로 조금씩 변형하며 사용하면 될 것 같다.
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
#include <iostream>
#include <queue>
#include <utility>
using namespace std;
int main(void){
ios:: sync_with_stdio(0);
cin.tie(0);
int arr[100][100] =
{ {1,1,1,0,1,0,0,0,0,0},
{1,0,0,0,1,0,0,0,0,0},
{1,1,1,0,1,0,0,0,0,0},
{1,1,0,0,1,0,0,0,0,0},
{0,1,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0} };
bool isVisited[100][100];
pair<int, int> dir[4] = {
pair<int, int>(-1, 0),
pair<int, int>(1, 0),
pair<int, int>(0, -1),
pair<int, int>(0, 1)
};
int n = 7, m = 10;
queue<pair<int, int> > q;
isVisited[0][0] = 1;
q.push(pair<int, int>(0, 0));
while(!q.empty()){
pair<int, int> cur = q.front();
q.pop();
cout << "(" << cur.first << "," << cur.second << ") -> ";
for(int i = 0; i < 4; i++){
int adjX = cur.first + dir[i].first;
int adjY = cur.second + dir[i].second;
if(adjX < 0 || adjX >= n || adjY < 0 || adjY >= m) continue;
if (isVisited[adjX][adjY] == true || arr[adjX][adjY] == 0) continue;
isVisited[adjX][adjY] = true;
q.push(pair<int, int>(adjX, adjY));
}
}
cout << "end" << "\n";
}
선언과 초기화
- line 10 ~ 17 : 다차원 배열을 선언한다. (주어진 다차원 배열을 저장한다.)
- line 19 : 각 칸의 방문 여부를 확인하기 위해 다차원 배열과 같은 크기의 배열을 선언한다.
- line 21 ~ 26 : 22줄부터 순서대로 배열의 상, 하, 좌, 우 좌표를 구할 방향 좌표이다.
- line 28 : 각 칸의 좌표를 담을 pair 형 queue를 선언한다.
탐색 과정
- line 32 : 시작점인 (0,0)을 방문했다고 명시한다. 시작점은 들어오는 다차원 배열에 따라 다르다.
-
line 33 : queue에 시작점인 (0,0)을 삽입한다.
- line 35 : queue에 남은 노드가 없을 때까지 반복한다.
- line 36 ~ 37 : queue의 가장 앞에 있는 노드를 확인한다.
- line 39 : 탐색 과정을 출력한다.
- line 41 : 해당 칸의 상하좌우로 인접한 칸을 탐색한다.
- line 45 : 탐색하는 칸이 범위 밖일 경우 탐색하지 않는다.
- line 46 : 인접한 칸이 이미 방문했던 칸이거나 빈 칸이라면 탐색하지 않는다.
- line 47 ~ 48 : 방문한 칸을 명시하고 queue에 방문한 칸을 삽입한다.
💡 주의해야 할 점
- 시작점에 방문했다는 표시를 해야 한다.
- 방문한 칸을 큐에서 뺄 때가 아닌 큐에 넣을 때 명시해야 한다. (같은 칸이 큐에 여러 번 들어가게 되어 시간 초과나 메모리 초과의 위험성 있음)
- 인접한 칸의 범위를 벗어날 경우 탐색할 수 없다.
댓글남기기