[백준][c++] 2206번: 벽 부수고 이동하기
2024. 2. 19. 15:49ㆍBOJ
2206번: 벽 부수고 이동하기
N×M의 행렬로 표현되는 맵이 있다. 맵에서 0은 이동할 수 있는 곳을 나타내고, 1은 이동할 수 없는 벽이 있는 곳을 나타낸다. 당신은 (1, 1)에서 (N, M)의 위치까지 이동하려 하는데, 이때 최단 경로
www.acmicpc.net
문제 해석
- N*M 배열의 1,1 에서 N,M까지의 최단경로를 찾아내는 문제
- 0은 벽이 없고 1은 벽이 있는 칸
- 벽은 최대 한번까지 부술수 있다.
풀이
큐를 이용한 BFS(너비 우선 탐색)으로 최단경로를 찾았습니다.
코드
#include <iostream>
#include <deque>
#include <vector>
#include <queue>
#include <climits>
using namespace std;
//입력부
static int n,m;
static int least = INT_MAX; //이동 횟수
vector<vector<int>> arr;
vector<vector<int>> visited;
static int dx[4] = {-1,1,0,0};
static int dy[4] = {0,0,-1,1};
//블록 구조체
struct point{
int x,y,time,blockCrashed;
point(int x, int y, int time, int blockCrashed) : x(x), y(y), time(time), blockCrashed(blockCrashed) {}
};
//해결부
void bfs(int x, int y){
queue<point> q;
q.push(point(x, y, 1, 0));
visited[y][x] = 0;
while (!q.empty()){
point current = q.front();
q.pop();
//종점일 경우
if(current.y ==n-1 &¤t.x == m-1){
least = current.time;
break;
}
//좌우양옆 탐색
for(int i=0; i<4; i++){
int nx = current.x + dx[i];
int ny = current.y + dy[i];
//(배열의 범위를 넘어감 || 경로가 더 길 경우) -> continue
if(!(0 <= nx && nx < m && 0 <=ny && ny < n) || visited[ny][nx] <= current.blockCrashed){
continue;
}
//이동 가능한 곳
if(arr[ny][nx] == 0){
visited[ny][nx] = current.blockCrashed;
q.push(point(nx, ny, current.time+1, current.blockCrashed));
}
//벽이 있는 곳
else{
if(current.blockCrashed == 0){
visited[ny][nx] = current.blockCrashed + 1;
q.push(point(nx, ny, current.time+1, current.blockCrashed+1));
}
}
}
}
}
int main() {
cin >> n >> m;
arr = vector<vector<int>>(n, vector<int>(m));
visited = vector<vector<int>>(n, vector<int>(m, INT_MAX));
for(int i=0;i<n;i++){
string str;
cin >> str;
for(int j=0; j<m; j++){
arr[i][j] = str[j]-'0';
}
}
bfs(0,0);
cout << (least == INT_MAX ? -1 : least) << endl;
return 0;
}
'BOJ' 카테고리의 다른 글
[백준][JAVA] 1305번: 광고 (0) | 2024.06.17 |
---|---|
[백준][c++] 12738번: 가장 긴 증가하는 부분 수열 3 (0) | 2024.01.10 |
[백준][c++] 1918번: 후위표기식 (0) | 2024.01.08 |
[백준][c++] 11003번: 최솟값 찾기 (1) | 2024.01.05 |