Skip to content

Commit 3a46c17

Browse files
committed
[Gold III] Title: 벽 부수고 이동하기, Time: 160 ms, Memory: 27972 KB -BaekjoonHub
1 parent 073730b commit 3a46c17

2 files changed

Lines changed: 111 additions & 0 deletions

File tree

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
# [Gold III] 벽 부수고 이동하기 - 2206
2+
3+
[문제 링크](https://www.acmicpc.net/problem/2206)
4+
5+
### 성능 요약
6+
7+
메모리: 27972 KB, 시간: 160 ms
8+
9+
### 분류
10+
11+
그래프 이론, 그래프 탐색, 너비 우선 탐색, 격자 그래프
12+
13+
### 제출 일자
14+
15+
2025년 11월 12일 18:36:21
16+
17+
### 문제 설명
18+
19+
<p>N×M의 행렬로 표현되는 맵이 있다. 맵에서 0은 이동할 수 있는 곳을 나타내고, 1은 이동할 수 없는 벽이 있는 곳을 나타낸다. 당신은 (1, 1)에서 (N, M)의 위치까지 이동하려 하는데, 이때 최단 경로로 이동하려 한다. 최단경로는 맵에서 가장 적은 개수의 칸을 지나는 경로를 말하는데, 이때 시작하는 칸과 끝나는 칸도 포함해서 센다.</p>
20+
21+
<p>만약에 이동하는 도중에 한 개의 벽을 부수고 이동하는 것이 좀 더 경로가 짧아진다면, 벽을 한 개 까지 부수고 이동하여도 된다.</p>
22+
23+
<p>한 칸에서 이동할 수 있는 칸은 상하좌우로 인접한 칸이다.</p>
24+
25+
<p>맵이 주어졌을 때, 최단 경로를 구해 내는 프로그램을 작성하시오.</p>
26+
27+
### 입력
28+
29+
<p>첫째 줄에 N(1 ≤ N ≤ 1,000), M(1 ≤ M ≤ 1,000)이 주어진다. 다음 N개의 줄에 M개의 숫자로 맵이 주어진다. (1, 1)과 (N, M)은 항상 0이라고 가정하자.</p>
30+
31+
### 출력
32+
33+
<p>첫째 줄에 최단 거리를 출력한다. 불가능할 때는 -1을 출력한다.</p>
34+
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
#include <iostream>
2+
#include <queue>
3+
#include <tuple>
4+
5+
#define MAX 1005
6+
7+
using namespace std;
8+
9+
int N, M;
10+
int maps[MAX][MAX]{};
11+
int visited[MAX][MAX][5]{};
12+
int dx[5] = {0, 0, 1, -1};
13+
int dy[5] = {1, -1, 0, 0};
14+
int flag = 0;
15+
int answer = 1e9;
16+
17+
void input() {
18+
cin >> N >> M;
19+
for (int i = 1; i <= N; i++) {
20+
char inputs;
21+
for (int j = 1; j <= M; j++) {
22+
cin >> inputs;
23+
int temp = inputs - '0';
24+
maps[i][j] = temp;
25+
}
26+
}
27+
}
28+
29+
void bfs() {
30+
queue<tuple<int, int, int, int>> q;
31+
q.push({1, 1, 1, 0}); // x, y, 거리, 벽 뚫은 여부
32+
visited[1][1][0] = 1;
33+
34+
while (!q.empty()) {
35+
int cx = get<0>(q.front());
36+
int cy = get<1>(q.front());
37+
int dist = get<2>(q.front());
38+
int wall = get<3>(q.front());
39+
q.pop();
40+
41+
if (cx == N && cy == M) {
42+
answer = min(answer, dist);
43+
flag = 1;
44+
continue; // 도달하면, 더 진행할 필요 없잖아?
45+
}
46+
47+
for (int i = 0; i < 4; i++) {
48+
int nx = cx + dx[i];
49+
int ny = cy + dy[i];
50+
51+
// 범위 나가면, 건너뛰기
52+
if (nx <= 0 || nx >= N+1 || ny <= 0 || ny >= M+1) continue;
53+
54+
if (wall == 0 && maps[nx][ny] == 1) {
55+
q.push({nx, ny, dist + 1, wall + 1});
56+
visited[nx][ny][wall + 1] = 1;
57+
} else if (!visited[nx][ny][wall] && !maps[nx][ny]) {
58+
q.push({nx, ny, dist + 1, wall});
59+
visited[nx][ny][wall] = 1;
60+
}
61+
}
62+
}
63+
}
64+
65+
int main() {
66+
input();
67+
68+
bfs();
69+
70+
if (flag) {
71+
cout << answer;
72+
} else {
73+
cout << -1;
74+
}
75+
76+
return 0;
77+
}

0 commit comments

Comments
 (0)