2206번: 벽 부수고 이동하기
N×M의 행렬로 표현되는 맵이 있다. 맵에서 0은 이동할 수 있는 곳을 나타내고, 1은 이동할 수 없는 벽이 있는 곳을 나타낸다. 당신은 (1, 1)에서 (N, M)의 위치까지 이동하려 하는데, 이때 최단 경로
www.acmicpc.net
범주: BFS, 3차원 배열을 이용한 DP
시간복잡도: O(N*M)
설명:
BFS를 진행하면서 2가지 상황에서 이동이 가능하다.
전제) 다음 노드는 한번도 접근되지 않은 노드이므로 최소 경로임이 보장된다.
1) 다음 노드는 벽이 아니다(pos[r][c] == 0).
2) 다음 노드는 벽이지만(pos[r][c] == 1), 현재 노드는 벽을 부수지 않고 진행했다.
시도:
1) 백트래킹 -> 시간 초과
2) 2차원 배열 DP -> 4방향을 이용한 DP는 힘들다
가져갈 수 있는 팁:
1) 띄어쓰기로 표현되지 않은 입력은 scanf("%1d", __ )로 받아준다.
2) 3개 이상의 멤버들을 필요로 하는 경우, struct를 사용하는 것이 편하다.
(다른 방법: pair<pair<int, int> >)
3) 3차원 배열을 이용해서 장애물 index를 마련하여 최적화를 시도할 수 있다.
#include<bits/stdc++.h>
using namespace std;
struct axis
{
int row;
int col;
int wall;
};
int N, M;
int pos[1001][1001];
int dist[1001][1001][2];
int orient[4][2] = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}};
void bfs()
{
queue<axis> q;
q.push({0,0,0});
dist[0][0][0] = 1;
while(!q.empty())
{
int r = q.front().row;
int c = q.front().col;
int w = q.front().wall;
q.pop();
if(r == N -1 && c == M - 1)
{
cout << dist[r][c][w];
return;
}
for(int i = 0; i < 4; i++)
{
int nr = r + orient[i][0];
int nc = c + orient[i][1];
if(nr < 0 || nr >= N || nc < 0 || nc >= M) continue;
if(pos[nr][nc] == 0 && dist[nr][nc][w] == 0)
{
dist[nr][nc][w] = dist[r][c][w] + 1;
q.push({nr, nc, w});
}
else if(pos[nr][nc] == 1 && w == 0 && dist[nr][nc][w+1] == 0)
{
dist[nr][nc][w+1] = dist[r][c][w] + 1;
q.push({nr, nc, w+1});
}
}
}
cout << -1;
return;
}
int main()
{
cin >> N >> M;
for(int i = 0; i < N; i++)
{
for(int j = 0; j < M; j++)
{
scanf("%1d", &pos[i][j]);
}
}
bfs();
return 0;
}
주의할 점:
계속해서 문제를 틀렸었는데 그 이유는 ios::sync_with_stdio(NULL)를 쓰고 scanf와 cin을 같이 썼기 때문이다.
ios::sync_with_stdio(NULL)는 c++의 iostream과 c의 stdio를 동기화시켜주는데 이 경우, scanf와 cin을 같이 쓰면 문제가 생긴다.
-해결책
1) ios::sync_with_stdio(NULL) 지우거나
2) cin >> N >> M 을 scanf("%d %d", &N, &M)으로 바꾸거나
3) scanf("%1d", &pos[i][j])말고, string으로 한번에 받은 뒤에 같은 열의 값들을 pos에 나누어준다.
'BOJ' 카테고리의 다른 글
[BOJ] 11976 최소 스패닝 트리(크루스칼 알고리즘) (0) | 2021.08.20 |
---|---|
[BOJ] 1865 웜홀(벨만 포드) (0) | 2021.08.18 |
[BOJ] 4095 최대 정사각형(DP) , 11660 구간 합 구하기 5(DP) (5) | 2021.04.14 |
[BOJ] 1516 게임 개발(DFS+DP or 위상 정렬+DP) (0) | 2021.04.05 |
[BOJ] 1987 알파벳(DFS, 백트래킹) (0) | 2021.03.29 |