728x90
https://www.acmicpc.net/problem/2206
이 문제는 단순 bfs문제 + 벽을 한번 부술 수 있다는 특징이 있는 문제이다.
주요 풀이는 다음과 같다.
3차원 배열을 선언하여 거리를 저장해주는데
벽을 부수고 이동하면 [x][y][0] 에 값을 저장해주고 벽을 안부수고 이동했다면 [x][y][1]에 값을 저장해준다.
다음 이동할 좌표가 맵의 범위 안이라면, 2가지 경우로 나눈다.
1. 벽을 만났는데, 뚫을 수 있는 경우 : 해당 좌표를 큐에 넣고(=벽을 뚫고 이동) 그 이전까지는 벽을 아직 뚫지 않았기 때문에
visited[nx][ny][1] + 1 값을 visited[nx][ny][0]에 넣는다.
즉, 벽을 안부수고 이동해온 거리에 + 1 해주는 것이다. 근데 이젠 벽을 부쉈으므로 세번째 인덱스가 0이 되는 것!
2. 이동 가능한 좌표를 만났는데, 방문하지 않은 경우 : 거리 + 1 해주고 큐에 넣어준다(=기본적인 bfs)
이외의 경우는 따지지 않아도 된다!
이외의 경우라 함은
1. 벽을 만났는데, 뚫을 수 없는 경우 : 무시하면 된다
2. 이동 가능한 좌표를 만났는데, 방문한 경우 : 무시하면 된다.
#include<iostream>
#include<algorithm>
#include<vector>
#include<queue>
#include<cstring>
#include<string>
using namespace std;
int map[1001][1001];
int visited[1001][1001][2];
// 1은 벽 안부순거, 0은 부순거
queue<pair<pair<int,int>,int>> q;
string str;
int n,m;
int dx[] = {1,0,-1,0};
int dy[] = {0,1,0,-1};
int bfs(){
q.push({{1,1},1});
visited[1][1][1]=1;
while(!q.empty()){
int x = q.front().first.first;
int y = q.front().first.second;
int wall = q.front().second;
q.pop();
if(x==n && y==m) return visited[x][y][wall];
for(int i=0; i<4; i++) {
int nx = x + dx[i];
int ny = y + dy[i];
if (nx >= 1 && nx <= n && ny >= 1 && ny <=m) {
if(wall == 1 && map[nx][ny]==1){ // 벽인데 뚫을 수 있는 상태
q.push({{nx,ny},0});
visited[nx][ny][0] = visited[x][y][1] + 1;
}
else if(map[nx][ny]==0 && visited[nx][ny][wall]==0){
q.push({{nx,ny},wall});
visited[nx][ny][wall] = visited[x][y][wall] + 1;
}
}
}
}
return -1;
}
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
cout.tie(nullptr);
cin >> n >> m;
for(int i=1; i<=n;i++){
cin >> str;
for(int j=1; j<=str.size();j++){
map[i][j] = str[j-1]-48;
}
}
int ans = bfs();
cout << ans;
return 0;
}
728x90
'알고리즘 > 백준(BOJ)' 카테고리의 다른 글
[백준/C++] 16236번 아기상어 (0) | 2022.09.29 |
---|---|
[백준/C++] 9328번 열쇠 (0) | 2022.09.29 |
[백준/C++] 2638번 치즈 (0) | 2022.09.29 |
[백준/C++] 16954 움직이는 미로탈출 (0) | 2022.09.29 |
[백준/C++] 11657번 타임머신 (0) | 2022.09.29 |