[BOJ] 탈옥
Date:
[BOJ] 탈옥
Problem URL : 탈옥
#include <cstring>
#include <deque>
#include <vector>
#include <iostream>
#define p pair<int,int>
using namespace std;
int h, w;
char map[102][102];
int dist[102][102][3];
vector<p> people;
int dx[4] = { -1, 0, 1, 0 };
int dy[4] = { 0, -1, 0, 1 };
void bfs(int nth) {
deque<p> dq;
dq.push_front({ people[nth].first, people[nth].second });
dist[people[nth].first][people[nth].second][nth] = 0;
while (!dq.empty()) {
int x = dq.front().first;
int y = dq.front().second;
dq.pop_front();
for (int dir = 0; dir < 4; dir++) {
int nx = x + dx[dir];
int ny = y + dy[dir];
if (nx < 0 || nx > h + 1 || ny < 0 || ny > w + 1 || dist[nx][ny][nth] >= 0 || map[nx][ny] == '*') continue;
if (map[nx][ny] == '.') {
dist[nx][ny][nth] = dist[x][y][nth];
dq.push_front({ nx, ny }); // dist가 증가하지 않았으므로 우선탐색
} else if (map[nx][ny] == '#') {
dist[nx][ny][nth] = dist[x][y][nth] + 1;
dq.push_back({ nx, ny }); // dist가 증가했으므로 나중에 탐색
}
}
}
}
int main() {
ios_base::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL);
int TC;
cin >> TC;
for (int tc=1; tc <=TC; tc++) {
memset(dist, -1, sizeof(dist));
memset(map, '.', sizeof(map));
people.clear();
cin >> h >> w;
for (int i = 1; i <= h; i++) {
string str = "";
cin >> str;
for (int j = 1; j <= w; j++) {
map[i][j] = str[j - 1];
if (map[i][j] == '$') {
map[i][j] = '.';
people.push_back({ i, j });
}
}
}
people.push_back({ 0,0 });
for (int i = 0; i < 3; i++) {
bfs(i);
}
int ans = 1e9;
for (int i = 0; i <= h + 1; i++) {
for (int j = 0; j <= w + 1; j++) {
if (map[i][j] == '*') continue;
int cnt = dist[i][j][0] + dist[i][j][1] + dist[i][j][2];
if (cnt == -3) continue; // [1]
if (map[i][j] == '#') cnt -= 2; // [2]
if (ans > cnt) ans = cnt;
}
}
cout << ans << endl;
}
return 0;
}
Comments
[1] 이 조건이 없으면 다음과 같은 반례가 생긴다.
1
7 7
***#***
*.....*
*.***.*
*#*.*#*
*.***.*
*.$*$.*
*******
즉 이동할 수 없는 공간이 있으면 그곳은 dist가 갱신이 안되고 세개의 dist가 -1값을 갖는다.
[2] 세가지 dist를 더할 때 벽(‘#’) 위치에서 더하면 3번 중복된다. 그래서 -2를 해주자.
댓글