무지성 공부방/알고리즘 해결
[BOJ_C++] 5427번: 불
hyerang0125
2022. 10. 10. 12:37
CODE
#include <bits/stdc++.h>
using namespace std;
#define X first
#define Y second
int tc, w, h;
string board[1002];
int dist[1002][1002];
int fire_dist[1002][1002];
int dx[4] = {1, 0, 0, -1};
int dy[4] = {0, 1, -1, 0};
int main()
{
ios_base::sync_with_stdio(0);
cin.tie(0);
cin >> tc;
while(tc--){
queue<pair<int, int>> fire;
queue<pair<int, int>> q;
bool flag = false;
memset(dist, -1, sizeof(dist));
memset(fire_dist, -1, sizeof(fire_dist));
cin >> w >> h;
for(int i=0; i<h; i++)
cin >> board[i];
for(int i=0; i<h; i++){
for(int j=0; j<w; j++){
if(board[i][j] == '@'){
q.push(make_pair(i, j));
dist[i][j] = 0;
}
if(board[i][j] == '*'){
fire.push(make_pair(i,j));
fire_dist[i][j] = 0;
}
}
}
while(!fire.empty()){
auto cur = fire.front(); fire.pop();
for(int dir=0; dir<4; dir++){
int nx = cur.X + dx[dir];
int ny = cur.Y + dy[dir];
if(nx < 0 || nx >= h || ny < 0 || ny >= w) continue;
if(fire_dist[nx][ny] != -1 || board[nx][ny] == '#') continue;
fire_dist[nx][ny] = fire_dist[cur.X][cur.Y] + 1;
fire.push(make_pair(nx, ny));
}
}
while(!q.empty()){
auto cur = q.front(); q.pop();
for(int dir=0; dir<4; dir++){
int nx = cur.X + dx[dir];
int ny = cur.Y + dy[dir];
if(nx < 0 || nx >= h || ny < 0 || ny >= w){
cout << dist[cur.X][cur.Y] + 1 << '\n';
flag = true; break;
}
if(board[nx][ny] == '#' || board[nx][ny] == '*') continue;
if(dist[nx][ny] != -1) continue;
if((dist[cur.X][cur.Y] + 1 >= fire_dist[nx][ny]) && fire_dist[nx][ny] != -1) continue;
dist[nx][ny] = dist[cur.X][cur.Y] + 1;
q.push(make_pair(nx, ny));
}
if(flag) break;
}
if(!flag) cout << "IMPOSSIBLE\n";
}
return 0;
}
풀이
- 불의 전파 시간과 상근이의 이동 시간을 측정하기 위한 dist와 fire_dist를 각각 -1로 초기화 한다.
- 빌딩의 지도를 입력받으며 불의 위치와 상근이의 위치를 큐에 넣고 시작의 의미로 거리를 0으로 초기화 한다.
- 먼저 불에 대한 BFS를 돌며 불의 전파 시간에 대하여 알아둔다. (상근이는 불이 붙은 곳에 가지 못하기 때문)
- 이후 상근이에 대한 BFS를 돈다.
- 만약 범위를 벗어났다면 탈출에 성공했다는 의미로 탈출한 시간을 출력한다.
- 만약 다음 위치가 벽이거나 불이라면 다음 위치를 탐색한다.
- 만약 다음 위치가 불이 옮겨 붙은 곳이라면 다음 위치를 탐색한다.
- 아니면 다음 위치에 전파 시간을 넣고 큐에 다음 위치를 넣어 BFS 탐색을 진행한다.
- 만약 위에서 아무 값도 출력하지 못해 flag가 false라면 탈출이 불가능한 것이므로 IMPOSSIBE을 출력한다.