이우의 개발일지
[백준 / C++] 2178 미로탐색 - BFS, stoi 본문
백준 2178번 미로 탐색 문제
https://www.acmicpc.net/problem/2178
문제
N×M크기의 배열로 표현되는 미로가 있다.
1 | 0 | 1 | 1 | 1 | 1 |
1 | 0 | 1 | 0 | 1 | 0 |
1 | 0 | 1 | 0 | 1 | 1 |
1 | 1 | 1 | 0 | 1 | 1 |
미로에서 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
미로 탐색 코드 풀이
이 문제의 핵심은 다른 BFS 문제로 크게 다를 것이 없지만, 차이점은 미로를 한칸씩 띄어서 주는 것이 아니라 한 행을 한번에 준다는 것이다..
그래서 2가지 방법을 떠올렸다.
1. stoi (string to int)
2. ASCII 코드로 변환
먼저 첫번째 방법인 stoi를 사용했다.
for (int i = 1; i <= n; i++) {
cin >> change;
int ex = stoi(change);
miro[i][m] = ex % 10;
ex /= 10;
for (int j = m-1; j > 0; j--) {
miro[i][j] = ex % 10;
ex /= 10;
}
}
String 문 전체를 int로 바꾸고, 그에 따라 뒤에 1의 자리부터 miro라는 배열에 넣어주고 변환된 값은 10으로 나눠주었다.
But...
이렇게 했을 때 문제점은 int의 범위가 -2,147,483,648 ~ 2,147,483,647 인데 한 행에 있을 수 있는 숫자는 최대 100개이기 때문에 int나 long을 해도 전체 숫자를 받을 수 없다는 단점이 있었다..
2번째 방법은 생각보다 훨씬 간단했다.
for (int i = 1; i <= n; i++) {
cin >> change;
for (int j = 1; j <= m; j++) {
int ex = change[j - 1] - 48;
miro[i][j] = ex;
}
}
String 앞에서부터 한자리씩 int로 변환해주면 된다.
아래 ASCII 코드 표를 보면 0은 48이기 때문에 48을 빼주면 된다.
이렇게 간단하게, 숫자로 변환하고 Miro 배열에 넣어주니 나머지는 BFS로 간단하게 해결됐다.
미로 탐색 전체 코드
#include<iostream>
#include<string>
#include<queue>
using namespace std;
int miro[101][101] = { 0, };
queue<pair<int,int>> que;
bool check[101][101] = { 0, };
int dx[4] = { 1, 0 , -1 ,0 };
int dy[4] = { 0, 1, 0 ,-1 };
int main() {
int n, m;
cin >> n >> m;
string change;
for (int i = 1; i <= n; i++) {
cin >> change;
for (int j = 1; j <= m; j++) {
int ex = change[j - 1] - 48;
miro[i][j] = ex;
}
}
que.push({ 1,1 });
check[1][1] = 1;
while (!que.empty()) {
pair<int, int> point = que.front();
que.pop();
for (int i = 0; i < 4; i++) {
int X = point.first + dx[i];
int Y = point.second + dy[i];
if (X > 0 && Y > 0 && X <= n && Y <= m) {
if (miro[X][Y] == 1 && check[X][Y] == 0) {
miro[X][Y] = miro[point.first][point.second] + 1;
que.push({ X,Y });
check[X][Y] = 1;
}
}
}
}
cout << miro[n][m];
return 0;
}
'Coding' 카테고리의 다른 글
[백준 / C++] 11660번 구간 합 구하기 5 - (1), DP (0) | 2025.01.11 |
---|---|
[백준 / C++] 12865 평범한 배낭 - (1) DP (0) | 2025.01.10 |
[백준 / C++] 18870번 좌표 압축 - map, priority queue, lower bound (0) | 2025.01.07 |
[백준 / C++] 1074번 Z - 재귀 (1) (0) | 2025.01.06 |
[백준 / C++] 2630번 색종이 만들기 - 재귀 (1) (1) | 2025.01.05 |