미로 탐색
https://www.acmicpc.net/problem/2178
| 시간 제한 | 메모리 제한 | 제출 | 정답 | 맞힌 사람 | 정답 비율 |
|---|---|---|---|---|---|
| 1 초 | 192 MB | 146493 | 63731 | 40916 | 42.227% |
문제
N×M크기의 배열로 표현되는 미로가 있다.

미로에서 1은 이동할 수 있는 칸을 나타내고, 0은 이동할 수 없는 칸을 나타낸다.
이러한 미로가 주어졌을 때, (1, 1)에서 출발하여 (N, M)의 위치로 이동할 때 지나야 하는 최소의 칸 수를 구하는 프로그램을 작성하시오.
한 칸에서 다른 칸으로 이동할 때, 서로 인접한 칸으로만 이동할 수 있다.
위의 예에서는 15칸을 지나야 (N, M)의 위치로 이동할 수 있다. 칸을 셀 때에는 시작 위치와 도착 위치도 포함한다.
입력
첫째 줄에 두 정수 N, M(2 ≤ N, M ≤ 100)이 주어진다.
다음 N개의 줄에는 M개의 정수로 미로가 주어진다.
각각의 수들은 붙어서 입력으로 주어진다.
출력
첫째 줄에 지나야 하는 최소의 칸 수를 출력한다.
항상 도착 위치로 이동할 수 있는 경우만 입력으로 주어진다.
예제 입력 1
4 6 101111 101010 101011 111011
예제 출력 1
15
예제 입력 2
4 6 110110 110110 111111 111101
예제 출력 2
9
예제 입력 3
2 25 1011101110111011101110111 1110111011101110111011101
예제 출력 3
38
예제 입력 4
7 7 1011111 1110001 1000001 1000001 1000001 1000001 1111111
예제 출력 4
13
출처
알고리즘 분류
입력 확인 코드
문제에서 ‘각각의 수들은 붙어서 입력으로 주어진다.’
이 부분은 string 으로 입력을 받고 string의 인덱스를 순회하면서 맵 배열에 넣어 주었다.
#include <iostream>
using namespace std;
string str;
int N, M;
int map[101][101];
bool debug = true;
int main()
{
cin >> N >> M;
for (int i = 1; i <= N; i++) {
cin >> str;
for (int j = 0; j < M; j++) map[i][j + 1] = str[j] - '0'; // char -> int
}
if (debug) {
for (int i = 1; i <= N; i++) {
for (int j = 1; j <= M; j++) {
cout << map[i][j] << " ";
}
cout << "\n";
}
}
return 0;
}


디버깅

통과된 코드
#include <iostream>
#include <queue>
using namespace std;
string str;
int N, M, dx, dy;
// 처음 방문시에는 갈 수 있는지 없는지 확인(0, 1)
// 방문한 다음에는 몇번쨰로 방문 했는지 기록
int map[101][101];
// 해당 좌표에 방문을 했는지 체크
bool checkMap[101][101];
// 탐색하는 방향 설정 => 상, 하 ,좌 ,우
int dxdy[4][2] = { {-1, 0}, {1, 0}, {0, -1}, {0, 1} };
// BFS를 위한 Queue
queue<pair<int, int>> myQueue;
pair<int, int> tempPair;
// 디버그용 bool
bool debug = false;
int main()
{
cin >> N >> M;
for (int i = 1; i <= N; i++) {
cin >> str; // 입력을 문자열 자체로 받음
// string 의 인덱스를 이용하여 map에 마킹
// char -> int
for (int j = 0; j < M; j++) map[i][j + 1] = str[j] - '0';
}
// BFS를 시작하기위한 초기값 설정
checkMap[1][1] = true;
map[1][1] = 1; // 카운트
myQueue.push(make_pair(1, 1));
while (!myQueue.empty()) {
tempPair = myQueue.front();
myQueue.pop();
// 상/하/좌/우를 탐색하기 위한 반복문
for (int i = 0; i < 4; i++) {
dx = tempPair.first + dxdy[i][0];
dy = tempPair.second + dxdy[i][1];
// 문제의 범위를 벗어나는 경우 => 넘어간다.
if (dx == 0 || dy == 0 || dx > N || dy > M) continue;
// '0' 이동할 수 없는 칸 인 경우, 이미 방문한 곳 일 경우 => 넘어간다.
if (map[dx][dy] == 0 || checkMap[dx][dy] == true) continue;
map[dx][dy] = map[tempPair.first][tempPair.second] + 1; // 카운트를 올려준다.
checkMap[dx][dy] = true; // 방문처리
myQueue.push(make_pair(dx, dy));
if (dx == N && dy == M) { // 목적지에 도달했다면 중지
// 외부 while (!myQueue.empty())을 나가기 위해서
// Queue를 비워준다.
while (!myQueue.empty()) myQueue.pop();
break;
}
}
}
// 정답 출력(해당 위치에 도달하기위한 최소)
cout << map[N][M];
if (debug) { // 시각적 디버그용 코드
cout << "\n";
for (int i = 1; i <= N; i++) {
for (int j = 1; j <= M; j++) {
cout << map[i][j] << " ";
}
cout << "\n";
}
}
return 0;
}


![백준 5026번 (박사 과정, C++) [BAEKJOON]](https://lycos7560.com/wp-content/uploads/boj-og.png)
![백준 2559번 (수열, C++) [BAEKJOON]](https://lycos7560.com/wp-content/uploads/boj-og-1.png)
![백준 1162번 (도로포장, C++, Dijkstra) / 추가 반례 [BAEKJOON]](https://lycos7560.com/wp-content/uploads/2022/10/boj-og-1-2048x1070-1-1024x535.png)