[백준] 벽 부수고 이동하기 c++ (2206번)
2025. 5. 2. 18:50ㆍ코딩테스트
벽 부수고 이동하기
시간 제한메모리 제한제출정답맞힌 사람정답 비율
2 초 | 192 MB | 168809 | 45737 | 28546 | 23.990% |
문제
N×M의 행렬로 표현되는 맵이 있다. 맵에서 0은 이동할 수 있는 곳을 나타내고, 1은 이동할 수 없는 벽이 있는 곳을 나타낸다. 당신은 (1, 1)에서 (N, M)의 위치까지 이동하려 하는데, 이때 최단 경로로 이동하려 한다. 최단경로는 맵에서 가장 적은 개수의 칸을 지나는 경로를 말하는데, 이때 시작하는 칸과 끝나는 칸도 포함해서 센다.
만약에 이동하는 도중에 한 개의 벽을 부수고 이동하는 것이 좀 더 경로가 짧아진다면, 벽을 한 개 까지 부수고 이동하여도 된다.
한 칸에서 이동할 수 있는 칸은 상하좌우로 인접한 칸이다.
맵이 주어졌을 때, 최단 경로를 구해 내는 프로그램을 작성하시오.
입력
첫째 줄에 N(1 ≤ N ≤ 1,000), M(1 ≤ M ≤ 1,000)이 주어진다. 다음 N개의 줄에 M개의 숫자로 맵이 주어진다. (1, 1)과 (N, M)은 항상 0이라고 가정하자.
출력
첫째 줄에 최단 거리를 출력한다. 불가능할 때는 -1을 출력한다.
- 최단거리 탐색을 찾기 위해서는 지나간 좌표마다 이동 횟수를 업데이트 하는 것 까진 도달했으나, 벽을 부수면서 가는 로직을 찾는게 어려웠음
- 벽을 뚫는 여부를 저장하기 위해서는 이중 Pair 를 사용해야 함
- cin 값을 받아올때 char 혹은 string으로 받아올 것을 생각해야 함
#include <iostream>
#include <queue>
using namespace std;
int dx[4] = { -1,1,0,0 };
int dy[4] = { 0,0,-1,1 };
int arr[1001][1001];
//방문횟수를 저장하기 위한 배열 [2]는 벽을 뚫었는지 안뚫었는지 체크하기 위함
int visited[1001][1001][2];
int n, m;
int BFS()
{
queue<pair<pair<int, int>, int>> q;
q.push({ { 0,0 } , 0 });
visited[0][0][0] = 1;
while (false == q.empty())
{
pair<pair<int, int>, int> cur = q.front();
q.pop();
int x = cur.first.first;
int y = cur.first.second;
int wall = cur.second;
//도착지점에 왔다면 반환
if (x == n - 1 && y == m - 1)
{
return visited[x][y][wall];
}
for (int i = 0; i < 4; i++)
{
int nx = x + dx[i];
int ny = y + dy[i];
//arr를 벗어나지 않는지 부터 검사
if (nx >= 0 && ny >= 0 && nx < n && ny < m)
{
//벽이 없고, 아직 방문안한경우
if (arr[nx][ny] == 0 && false == visited[nx][ny][wall])
{
visited[nx][ny][wall] = visited[x][y][wall] + 1;
q.push({ { nx,ny },wall });
}
//벽이 있고, 벽을 뚫지 않은 경우
if (arr[nx][ny] == 1 && wall == 0)
{
visited[nx][ny][wall + 1] = visited[x][y][wall] + 1;
q.push({ {nx,ny},wall + 1 });
}
}
}
}
return -1;
}
int main()
{
cin >> n >> m;
for (int i = 0; i < n; i++)
{
for (int j = 0; j < m; j++)
{
char temp;
cin >> temp;
arr[i][j] = temp - '0';
}
}
cout << BFS();
}
'코딩테스트' 카테고리의 다른 글
[백준] 1,2,3 더하기 c++ (9095번) (0) | 2025.05.01 |
---|---|
[백준] 나이트의 이동 c++ (7562번) (0) | 2025.05.01 |
[백준] 섬의 개수 c++ (4963번) (0) | 2025.04.28 |
[백준] 숨바꼭질 c++ (1697번) (0) | 2025.04.26 |
[백준] 안전 영역 c++ (2468번) (0) | 2025.04.25 |