SWExpertAcademy의 오 ! 나의 여신님(7793 / D5) 문제이다.
[ 문제풀이 ]
현재 수연이가 위치한 곳에서, 악마의 손아귀 영역을 피해서 여신님께 갈 수 있는 최소시간을 구해야 하는 문제이다.
본인은 이 문제를 너비우선탐색(BFS) 방법을 이용해서 접근해보았는데, 총 2번의 BFS를 사용해 주었다.
첫 번째 BFS는 '악마들의 맵'을 생성하기 위해서 사용한 BFS이다.
초기에 악마가 존재하는 좌표들을 시작점으로, 모든 좌표에 악마의 손아귀가 퍼질 수 있는 최소시간을 구해서 저장하는
' 악마들의 맵'을 생성해주었다.
그 이후, 수연이를 BFS탐색을 통해서 여신님께 갈 수 있는지 판단해 주었다.
수연이의 BFS에서는 미리 만들어둔 악마들의 맵과 시간을 비교해가면서 이동하려는 좌표에 갈 수 있는지 없는지를
판단해주면서 구해주었다.
[ 소스코드 ]
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 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 | #include<iostream> #include<queue> #include<vector> #include<cstring> #include<string> #define endl "\n" #define MAX 50 #define INF 987654321 using namespace std; int N, M, Answer; char MAP[MAX][MAX]; int Devil_MAP[MAX][MAX]; bool Visit[MAX][MAX]; vector<pair<int, int>> Devil; pair<int, int> Start, End; string GameOver = "GAME OVER"; int dx[] = { 0, 0, 1, -1 }; int dy[] = { 1, -1, 0, 0 }; void Initialize() { memset(Visit, false, sizeof(Visit)); Devil.clear(); for (int i = 0; i < MAX; i++) { for(int j = 0 ; j < MAX; j++) { Devil_MAP[i][j] = INF; } } } void Input() { cin >> N >> M; for (int i = 0; i < N; i++) { for (int j = 0; j < M; j++) { cin >> MAP[i][j]; if (MAP[i][j] == 'S') { Start.first = i; Start.second = j; } else if (MAP[i][j] == 'D') { End.first = i; End.second = j; } else if (MAP[i][j] == '*') Devil.push_back(make_pair(i, j)); } } } void Make_Devil_MAP() { queue<pair<int, int>> Q; for(int i = 0 ; i < Devil.size(); i++) { int x = Devil[i].first; int y = Devil[i].second; Q.push(make_pair(x, y)); Devil_MAP[x][y] = 0; } while (Q.empty() == 0) { int x = Q.front().first; int y = Q.front().second; 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 < N && ny < M) { if (MAP[nx][ny] == 'X') continue; if (MAP[nx][ny] == 'D') continue; if (Devil_MAP[nx][ny] > Devil_MAP[x][y] + 1) { Devil_MAP[nx][ny] = Devil_MAP[x][y] + 1; Q.push(make_pair(nx, ny)); } } } } } int Move() { queue<pair<pair<int, int>, int>> Q; Q.push(make_pair(make_pair(Start.first, Start.second), 0)); Visit[Start.first][Start.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.first && y == End.second) return Cnt; for (int i = 0; i < 4; i++) { int nx = x + dx[i]; int ny = y + dy[i]; if (nx >= 0 && ny >= 0 && nx < N && ny < M) { if (MAP[nx][ny] == 'X') continue; if (Visit[nx][ny] == true) continue; if (Devil_MAP[nx][ny] > Cnt + 1) { Visit[nx][ny] = true; Q.push(make_pair(make_pair(nx, ny), Cnt + 1)); } } } } return -1; } void Solution() { Make_Devil_MAP(); Answer = Move(); } void Solve() { int Tc; cin >> Tc; for (int T = 1; T <= Tc; T++) { Initialize(); Input(); Solution(); cout << "#" << T << " "; if (Answer == -1) cout << GameOver << endl; else cout << Answer << endl; } } int main(void) { ios::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL); //freopen("Input.txt", "r", stdin); Solve(); return 0; } | cs |
'[ SWEA Code ] > # SWEA - ' 카테고리의 다른 글
[ SWEA 5672 ] 올해의 조련사 (C++) (0) | 2020.03.27 |
---|---|
[ SWEA 1803 ] Shortest Path Faster (C++) (0) | 2020.03.24 |
[ SWEA 3135 ] 홍준이의 사전 놀이 (C++) (0) | 2020.03.21 |
[ SWEA 5432 ] 쇠막대기 자르기 (C++) (0) | 2020.03.19 |
[ SWEA 1486 ] 장훈이의 높은 선반 (C++) (0) | 2020.03.19 |