#include <bits/stdc++.h>
using namespace std;
#define x first
#define y second
int dx[4] = { 1,-1,0,0 };
int dy[4] = { 0,0,1,-1 };
int n;
int vis1[1002][1002]; // 불
int vis2[1002][1002]; // 상근
string s[1001];
int main(void) {
ios::sync_with_stdio(0);
cin.tie(0);
cin >> n;
while (n--) {
int n, m;
cin >> m >> n;
// n x 축 // m y 축
bool escape = false;
for (int i = 0; i < n; i++) {
fill(vis1[i], vis1[i] + m, -1);
fill(vis2[i], vis2[i] + m, -1);
}
for (int i = 0; i < n; i++) cin >> s[i];
queue <pair<int, int>> q1 = {}; // 불
queue <pair<int, int>> q2 = {}; // 상근
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
if (s[i][j] == '*') {
vis1[i][j] = 0;
q1.push({ i,j });
}
else if (s[i][j] == '@') {
vis2[i][j] = 0;
q2.push({ i,j });
}
}
}
// 불의 이동경로 계산.
while (!q1.empty()) {
auto cur = q1.front(); q1.pop();
for (int i = 0; i < 4; i++) {
int nx = cur.x + dx[i];
int ny = cur.y + dy[i];
if (nx < 0 or nx >= n or ny < 0 or ny >= m or vis1[nx][ny]> -1 or s[nx][ny] == '#') continue;
q1.push({ nx,ny });
vis1[nx][ny] = vis1[cur.x][cur.y] + 1;
}
}
while ((!q2.empty()) && (!escape)) {
auto cur = q2.front(); q2.pop();
for (int i = 0; i < 4; i++) {
int nx = cur.x + dx[i];
int ny = cur.y + dy[i];
if (nx < 0 or nx >= n or ny < 0 or ny >= m) {
cout << vis2[cur.x][cur.y] + 1 << "\n";
escape = true;
break;
}
if (s[nx][ny] == '#' or vis2[nx][ny] > -1) continue;
if (vis1[cur.x][cur.y] < vis2[cur.x][cur.y] + 1 and vis1[cur.x][cur.y]> -1) continue;
// vis1[nx][ny] <= vis2[v.x][v.y] + 1 조건더 타이트하게 쓸 것.. -- > 여기서 시간 많이 잡아먹음
// (불이없는 경우) <-- 반례를 생각하지 못함
vis2[nx][ny] = vis2[cur.x][cur.y] + 1;
q2.push({ nx,ny });
}
}
if (escape == false) cout << "IMPOSSIBLE" << "\n";
}
}
주석처리를 조심하자 ( 주석부분에서 시간을 조금 많이 먹었다 )
알아야 할 것
1. string 입력 <-- 배열처럼 가능
2. 예외처리 ( 불의 유무 + vis1/2[nx] ? [x] ? 어떻게 비교할까??)
'알고리즘&자료구조 > 문제풀이' 카테고리의 다른 글
[백준] 30625 댄스타임 / c++ (0) | 2024.01.31 |
---|---|
14502 c++ 연구소 - 조합으로 풀기 (1) | 2023.12.10 |
[python] 7576 토마토 - 백준 / 출발지점이 여러개인 bfs 가 헷갈릴 때 다시볼것 (0) | 2022.02.03 |