
https://www.acmicpc.net/problem/5427
5427번: 불
문제 상근이는 빈 공간과 벽으로 이루어진 건물에 갇혀있다. 건물의 일부에는 불이 났고, 상근이는 출구를 향해 뛰고 있다. 매 초마다, 불은 동서남북 방향으로 인접한 빈 공간으로 퍼져나간다. 벽에는 불이 붙지 않는다. 상근이는 동서남북 인접한 칸으로 이동할 수 있으며, 1초가 걸린다. 상근이는 벽을 통과할 수 없고, 불이 옮겨진 칸 또는 이제 불이 붙으려는 칸으로 이동할 수 없다. 상근이가 있는 칸에 불이 옮겨옴과 동시에 다른 칸으로 이동할 수 있다. 빌딩
www.acmicpc.net
입력
- 상근이의 위치와 불의 위치를 각각 큐에 저장하였다.
- 테스트 케이스가 있는 문제이므로, 테스트 케이스의 결과를 출력한 뒤 상근이의 위치가 저장되어있는 큐와 불의 위치가 저장되어 있는 큐를 초기화 시켜주었다. 또한 방문배열, 전체 배열도 초기화 시켰다.
구현
- 상근이와 불은 동시에 번지고, 불이 번질 곳에는 상근이가 이동하지 못한다는 조건이 있기 때문에 불을 먼저 이동시켰다.
- 원래는 불이 번질 위치만 저장해두고 상근이를 먼저 이동시켰는데 불필요한 작업이 들어가는 것으로 생각한다. 또한, 시간초과가 날 수 있다
- 불의 확산은 bfs 탐색을 사용하였다.
- 이때, 이미 불이 번진 곳에도 불을 확산시켰더니 시간초과가 났었다
- 상근이의 이동 또한 bfs 탐색을 사용하였다.(불의 확산과 똑같음)
- 상근이가 이동하기 전, 탈출 조건을 먼저 확인하였다.
- 탈출조건은 상근이가 map의 가장자리에 위치하면 탈출이다. 이때도 1초가 지나고 상근이가 이동하는 것이므로 출력 시 1을 더해주었다.
- 상근이가 이동했다면, is_move 라는 flag 변수를 두어, 이동하지 못한 경우에는 IMPOSSIBLE를 출력할 수 있도록 하였다.
소스 코드
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include<iostream> | |
#include<queue> | |
#include<string.h> | |
#define endl "\n" | |
#define MAX 1000 | |
using namespace std; | |
struct INFO { | |
bool visit; // 방문했는지 | |
bool next_fire; // 다음에 불 날 위치인가 | |
}; | |
int t; | |
int w, h; | |
int result; // 정답 | |
bool visit[MAX][MAX]; | |
char map[MAX][MAX]; | |
//INFO visit[MAX][MAX]; | |
deque<pair<int, int>>sang;// 상근이의 위치 | |
queue<pair<int, int>>fire;// 불의 위치 | |
int dy[4] = { 0,0,1,-1 }; | |
int dx[4] = { 1,-1,0,0 }; | |
void ptr() { | |
for (int i = 0; i < h; i++) { | |
for (int j = 0; j < w; j++) { | |
cout << map[i][j] << ' '; | |
} | |
cout << endl; | |
} | |
cout << "=============" << endl; | |
} | |
void bfs() { | |
while(!sang.empty()) { | |
// 불 확산, 위치 저장 | |
bool is_move = false; | |
int fire_size = fire.size(); | |
for (int i = 0; i < fire_size; i++) { | |
int fire_y = fire.front().first; | |
int fire_x = fire.front().second; | |
fire.pop(); | |
for (int k = 0; k < 4; k++) { | |
int fire_ny = fire_y + dy[k]; | |
int fire_nx = fire_x + dx[k]; | |
if (0 > fire_ny || fire_ny >= h || 0 > fire_nx || fire_nx >= w) continue; | |
if (map[fire_ny][fire_nx] != '#' && map[fire_ny][fire_nx] != '*') { // 벽이 아니라면 불이 붙는다 | |
map[fire_ny][fire_nx] = '*'; | |
fire.push({ fire_ny,fire_nx }); // 새롭게 확산된 불의 위치 저장 | |
} | |
} | |
} | |
// 상근이 이동, 위치 저장 | |
int sang_size = sang.size(); | |
for (int i = 0; i < sang_size; i++) { | |
int y = sang.front().first; | |
int x = sang.front().second; | |
visit[y][x] = true; | |
sang.pop_front(); | |
if (y == 0 || y == h - 1 || x == 0 || x == w - 1) { | |
cout << result + 1 << endl; | |
return; | |
} | |
for (int k = 0; k < 4; k++) { | |
int ny = y + dy[k]; | |
int nx = x + dx[k]; | |
if (0 > ny || ny >= h || 0 > nx || nx >= w) continue; // 진행방향이 범위 초과 | |
if (map[ny][nx] == '#' || map[ny][nx] == '*' || visit[ny][nx] == true) continue; // 진행방향이 벽, 불, 방문했던 위치 | |
map[ny][nx] = '@'; | |
sang.push_back({ ny,nx }); | |
is_move = true; | |
visit[ny][nx] = true; | |
} | |
} | |
result++; | |
if (!is_move) { | |
cout << "IMPOSSIBLE" << endl; | |
return; | |
} | |
} | |
} | |
int main() { | |
ios::sync_with_stdio(false); | |
cin.tie(0); cout.tie(0); | |
cin >> t; | |
while (t--) { | |
result = 0; | |
cin >> w >> h; | |
for (int i = 0; i < h; i++) { | |
string str; | |
cin >> str; | |
for (int j = 0; j < w; j++) { | |
map[i][j] = str[j]; | |
if (str[j] == '@') { | |
sang.push_back({ i,j }); | |
} | |
else if (str[j] == '*') { | |
fire.push({ i,j }); | |
} | |
} | |
} | |
bfs(); | |
// 초기화 | |
while (!sang.empty())sang.pop_front(); | |
while (!fire.empty())fire.pop(); | |
memset(visit, false, sizeof(visit)); | |
memset(map, '#', sizeof(map)); | |
} | |
} |
'Problem Solving > 백준' 카테고리의 다른 글
[삼성 A형 기출문제] 17070 - 파이프 옮기기 1 (0) | 2020.02.28 |
---|---|
[삼성 A형 기출문제] - 17406 배열 돌리기 4 (0) | 2020.02.27 |
[삼성 SW 역량 테스트 기출 문제] 14502_연구소 (0) | 2020.02.22 |
[삼성 SW 역량 테스트 기출 문제] 14503_로봇 청소기 (0) | 2020.02.22 |
[삼성 A형 기출 문제] 17281 - ⚾ (0) | 2020.02.17 |