Study hard
(c++)백준 2206번: 벽 부수고 이동하기 본문
https://www.acmicpc.net/problem/2206
2206번: 벽 부수고 이동하기
N×M의 행렬로 표현되는 맵이 있다. 맵에서 0은 이동할 수 있는 곳을 나타내고, 1은 이동할 수 없는 벽이 있는 곳을 나타낸다. 당신은 (1, 1)에서 (N, M)의 위치까지 이동하려 하는데, 이때 최단 경로��
www.acmicpc.net
[풀이]
기존의 최단 경로를 구하는 bfs를 쓰지만, visited를 3차원 배열로 선언하여 그 좌표를 벽을 1번 부수고 방문했는지와 부수지 않고 방문했는지 여부를 표시해줬다.
#include <iostream>
#include <queue>
#include <cstdio>//scanf
using namespace std;
struct State {
int x, y;
int b_cnt, p_len;//벽을 부순 횟수, 이동한 거리
};
int N, M;
int Map[1001][1001];
bool visited[1001][1001][2];//x좌표, y좌표, 벽을 부순 적 있는지
const int dx[] = { -1,1,0,0 };//상하
const int dy[] = { 0,0,-1,1 };//좌우
int bfs() {
queue<State>q;
q.push({ 0,0,0,1 });
visited[0][0][0] = true;
int ans = -1;
while (!q.empty()) {
int x = q.front().x;
int y = q.front().y;
int b_cnt = q.front().b_cnt;
int p_len = q.front().p_len;
q.pop();
if (x == N - 1 && y == M - 1) {
ans = p_len;
break;
}
for (int i = 0; i < 4; i++) {
int nx = x + dx[i];
int ny = y + dy[i];
if (nx < 0 || nx >= N || ny < 0 || ny >= M)
continue;
//다음 칸이 벽인데 아직 벽 안 부쉈을 때
if (Map[nx][ny] == 1 && b_cnt == 0) {
visited[nx][ny][b_cnt + 1] = true;
q.push({ nx,ny,b_cnt + 1,p_len + 1 });
}
else if (Map[nx][ny] == 0 && visited[nx][ny][b_cnt] == false) {
visited[nx][ny][b_cnt] = true;
q.push({ nx,ny,b_cnt,p_len + 1 });
}
}
}
return ans;
}
void solution() {
cin >> N >> M;
for (int i = 0; i < N; i++) {
for (int j = 0; j < M; j++) {
scanf("%1d", &Map[i][j]);
}
}
cout << bfs() << '\n';
}
int main() {
solution();
return 0;
}
'백준 > bfs, dfs' 카테고리의 다른 글
(c++)백준 16933번: 벽 부수고 이동하기 3 (0) | 2020.08.31 |
---|---|
(c++)백준 14442번: 벽 부수고 이동하기 2 (0) | 2020.08.31 |
(c++)백준 14502번: 연구소 (0) | 2020.08.30 |
(c++)백준 9019번: DSLR (0) | 2020.08.29 |
(c++)백준 16948번: 데스 나이트 (0) | 2020.08.29 |