백준의 탈출(3055) 문제이다.
( 문제 바로가기 )
[ 문제풀이 ]
1. 본인은 이 문제를 해결할 때, 물에 대한 맵을 하나 만들었고, 그 물에 대한 맵과 고슴도치의 움직임을 비교하면서
해결해 나갔다.
2. 구체적으로 알아보자. 물은 1초마다 상하좌우로 퍼져나가게 된다. 즉, 현재 물이 있는 곳을 처음 Queue에 넣고 BFS-Leveling
방법을 통해서 물이 매 초 마다 갈 수 있는 맵을 따로 만들어 주었다.
문제를 보니, 처음 물이 시작하는 정점이 2개 이상일 때가 있기 때문에, BFS-Leveling 을 통해서 맵을 만들어 주었다.
3. 이제 고슴도치를 비버의 굴로 움직여보자. 3가지 조건에 대해서만 체크해보고 고슴도치를 움직여 주면 된다.
조건 1 : 아직 탐색한 적이 없는 정점인가 ?
조건 2 : 맵이 갈 수 있는 길인가?(바위가 아니인가?)
조건 3 : 탐색하려고 하는 정점에 도달하는데 걸리는 시간이, 물이 도달한 시간보다 작은가?
이 3가지에 대해서만 체크를 해주면 된다.
조건 1, 2는 기본적으로 BFS를 구현할 때, 기본적으로 항상 해줘야 하는 것이고 조건 3만 조금 더 신경써주면 될 것이다.
2번에서 만들어 놓은 물이 정점에 도달하는데 걸리는 시간을 체크해놓은 맵과 고슴도치가 현재 움직이는 시간을
비교해서
' 한 정점에 물이 도착하는데 걸리는 시간 > 고슴도치의 현재 시간 + 1 ' 이라면 고슴도치가 갈 수 있는 것이다.
고슴도치의 현재시간 + 1로 표현을 한 이유는, (x, y)에서 (nx, ny)로 움직일 때 1초가 더 걸리기 때문에
(x, y)에서 (nx,ny)로 가려고 하는데, 만약 현재 시간 + 1초를 한 시간이 물이 도착하는데 걸리는 시간보다 작다면
더 빠르다면 갈 수 있다 가 되는 것이다.
[ 소스코드 ]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 | #include<iostream> #include<queue> #define endl "\n" #define MAX 50 using namespace std; int R, C; int Water_MAP[MAX][MAX]; char MAP[MAX][MAX]; bool Visit[MAX][MAX]; int dx[] = { 0, 0, 1, -1 }; int dy[] = { 1, -1, 0, 0 }; pair<int, int> Start_Pos, End_Pos; queue<pair<int, int>> Water_Q; void Input() { cin >> R >> C; for (int i = 0; i < R; i++) { for (int j = 0; j < C; j++) { Water_MAP[i][j] = 999; } } for (int i = 0; i < R; i++) { for (int j = 0; j < C; j++) { cin >> MAP[i][j]; if (MAP[i][j] == 'S') { Start_Pos.first = i; Start_Pos.second = j; } else if (MAP[i][j] == 'D') { End_Pos.first = i; End_Pos.second = j; } else if (MAP[i][j] == '*') { Water_MAP[i][j] = 0; Water_Q.push(make_pair(i, j)); } } } } void Make_WaterMap() { while (Water_Q.empty() == 0) { int Qs = Water_Q.size(); for (int i = 0; i < Qs; i++) { int x = Water_Q.front().first; int y = Water_Q.front().second; Water_Q.pop(); for (int i = 0; i < 4; i++) { int nx = x + dx[i]; int ny = y + dy[i]; if (nx >= 0 && ny >= 0 && nx < R && ny < C) { if (MAP[nx][ny] == '.') { if (Water_MAP[nx][ny] > Water_MAP[x][y] + 1) { Water_MAP[nx][ny] = Water_MAP[x][y] + 1; Water_Q.push(make_pair(nx, ny)); } } } } } } } void Move() { queue<pair<pair<int, int>, int>> Q; Q.push(make_pair(make_pair(Start_Pos.first, Start_Pos.second), 0)); Visit[Start_Pos.first][Start_Pos.second] = true; while (Q.empty() == 0) { int x = Q.front().first.first; int y = Q.front().first.second; int Cnt = Q.front().second; Q.pop(); if (x == End_Pos.first && y == End_Pos.second) { cout << Cnt << endl; return; } for (int i = 0; i < 4; i++) { int nx = x + dx[i]; int ny = y + dy[i]; if (nx >= 0 && ny >= 0 && nx < R && ny < C) { if (Visit[nx][ny] == false && MAP[nx][ny] != 'X' && Water_MAP[nx][ny] > Cnt + 1) { Visit[nx][ny] = true; Q.push(make_pair(make_pair(nx, ny), Cnt + 1)); } } } } cout << "KAKTUS" << endl; } void Solution() { Make_WaterMap(); Move(); } void Solve() { Input(); Solution(); } int main(void) { ios::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL); //freopen("Input.txt", "r", stdin); Solve(); return 0; } | cs |
'[ BOJ Code ] > # BOJ -' 카테고리의 다른 글
[ 백준 2573 ] 빙산 (C++) (0) | 2019.01.03 |
---|---|
[ 백준 16198 ] 에너지 모으기 (C++) (0) | 2018.12.27 |
[ 백준 1963 ] 소수경로 (C++) (0) | 2018.12.26 |
[ 백준 3197 ] 백조의 호수 (C++) (2) | 2018.12.23 |
[ 백준 2589 ] 보물섬 (C++) (0) | 2018.12.23 |