아이디어는 어렵지 않은데 코드로 구현해내는 방식이 어려웠다.
cur.first.first 와 cur.first.second 에 각각 원숭이의 x, y좌표를
cur.second.first 와 cur.second.second에 각각 말처럼 이동한 횟수, 총이동 횟수를 저장하였다.
BFS과정을 통해 진행되며 도착점(오른쪽 하단)에 최초로 도착하게 될 때, cur.second.second + 1의 값을 출력한다.
(BFS특성상 cur.second.second의 값이 연속되게 큐에 들어가기 때문에 최초이후의 값은 최초보다 무조건 크거나 같다.)
//1600
#include <iostream>
#include <queue>
#include <deque>
using namespace std;
int board[200][200];
int vis[200][200][31];
int W, H, K;
int dx[12] = { 0, 0, -1, 1, 1, 1, 2, 2, -1, -1, -2, -2 };
int dy[12] = { -1, 1, 0, 0, 2, -2, 1, -1, 2, -2, 1, -1 };
queue<pair<pair<int, int>, pair<int, int>>> q;
void BFS() {
q.push({ {0, 0}, {0, 0} });
vis[0][0][1] = 1;
while (!q.empty()) {
pair<pair<int, int>, pair<int, int>> cur;
cur = q.front();
q.pop();
for (int dir = 0; dir < 12; dir++) {
if (dir >= 4 && cur.second.first >= K)
continue;
int nx = cur.first.first + dx[dir];
int ny = cur.first.second + dy[dir];
int nz = cur.second.first;
if (dir >= 4)
nz += 1;
if (nx < 0 || ny < 0 || nx >= H || ny >= W)
continue;
if (nx == H - 1 && ny == W - 1) {
cout << cur.second.second + 1;
return;
}
if (board[nx][ny] == 1 || (nx == 0 && ny == 0))
continue;
if (vis[nx][ny][nz] == 0) {
vis[nx][ny][nz] = vis[cur.first.first][cur.first.second][cur.second.first] + 1;
if (dir < 4) {
q.push({ { nx, ny}, {cur.second.first, cur.second.second + 1} });
}
else {
q.push({ { nx, ny}, {cur.second.first + 1, cur.second.second + 1} });
}
}
}
}
cout << -1;
}
int main(void) {
ios::sync_with_stdio(false);
cin.tie(NULL);
cin >> K >> W >> H;
for (int i = 0; i < H; i++)
for (int j = 0; j < W; j++)
cin >> board[i][j];
if (H == 1 && W == 1) {
cout << 0;
return 0;
}
BFS();
}
'알고리즘 > C++' 카테고리의 다른 글
[백준] 9466번 텀 프로젝트 (0) | 2021.03.13 |
---|---|
[백준] 4179번 불! (0) | 2021.03.13 |
[백준] 6198번 옥상 정원 꾸미기 (0) | 2021.03.08 |
[백준] 1406번 에디터 (0) | 2021.03.06 |
[백준] 3273번 두수의 합 (1) | 2021.03.06 |
댓글