문제/백준
c++ 백준_1600_"말이 되고픈 원숭이"
나 진짜 못차마
2023. 6. 15. 22:48
728x90
https://www.acmicpc.net/problem/1600
1600번: 말이 되고픈 원숭이
첫째 줄에 정수 K가 주어진다. 둘째 줄에 격자판의 가로길이 W, 세로길이 H가 주어진다. 그 다음 H줄에 걸쳐 W개의 숫자가 주어지는데, 0은 아무것도 없는 평지, 1은 장애물을 뜻한다. 장애물이 있
www.acmicpc.net
개인적으로 나한테 좀 어려웠다고 느낀다.
처음 접근은 말과 원숭이의 움직임으로 방문한 좌표를
visit, k_visit 두개로 나눠 따로 방문 체크를 하였다.
이렇게 하면 말의 움직임 1~2번 정도만 가능하였다.
그래서 처음으로 3차원 배열을 사용하였다.
각 층은 말의 움직임을 몇번 사용하고 방문했느냐다.
그냥 생각하다가 그려보고싶었다 헿

근데 그렇게 하더라도 약간 의문이 생겼다.
말의 움직임이 방문한 곳에 원숭이가 방문을 하고싶다면?
그건 어짜피 최소를 구하니까 말이 방문했다면
최소한 원숭이는 방문 못하는 곳이거나
원숭이보다 방문을 먼저 할 수 있어 움직임을 최소화할 수 있다.
살펴봤던 예시로
말 움직임 start : S
end : E
case 1

case 2

case 1의 경우 E 오른쪽 좌표가 원숭이 움직임으로 방문됐다고 체크 될 것이다.
case 2의 경우 말의 움직임으로 E 좌표를 방문을 해야되는데 원숭이가 방문했다고 체크 되면
방문을 못하게된다.
근데 BFS 특성상 최종좌표에 먼저 도달하게되면 그게 즉 최소 거리가 되니
크게 상관없던 것이였다.
괜한 생각을 많이했다.
#include <iostream>
#include <vector>
#include <queue>
using namespace std;
pair<int, int> horse_move[] = { {-1,-2},{-2,-1},{-2,1},{-1,2},
{1,2},{2,1},{2,-1},{1,-2} };
pair<int, int> monkey_move[] = { {-1,0},{0,1},{1,0},{0,-1} };
int K;
int W, H;
int board[201][201];
bool k_visit[201][201][31];
typedef struct {
int x, y;
int k_cnt;
int cnt;
}node;
bool is_in(int x, int y) {
if (x < 0 || y < 0 || x >= H || y >= W || board[x][y] == 1)
return false;
return true;
}
void BFS() {
queue<node> q;
node e;
e = { 0,0,0,0 };
q.push(e);
int ans = -1;
k_visit[0][0][0] = true;
while (!q.empty()) {
int x = q.front().x;
int y = q.front().y;
int k_cnt = q.front().k_cnt;
int cnt = q.front().cnt;
q.pop();
if (x == H - 1 && y == W - 1) {
ans = cnt;
break;
}
for (int i = 0; i < 4; i++) {
int dx = monkey_move[i].first;
int dy = monkey_move[i].second;
if (is_in(x + dx, y + dy)) {
if (!k_visit[x + dx][y + dy][k_cnt]) {
e = { x + dx,y + dy,k_cnt,cnt + 1 };
q.push(e);
k_visit[x + dx][y + dy][k_cnt] = true;
}
}
}
if (k_cnt < K) {
for (int i = 0; i < 8; i++) {
int dx = horse_move[i].first;
int dy = horse_move[i].second;
if (is_in(x + dx, y + dy)) {
if (!k_visit[x + dx][y + dy][k_cnt + 1]) {
e = { x + dx,y + dy,k_cnt + 1,cnt + 1 };
q.push(e);
k_visit[x + dx][y + dy][k_cnt + 1] = true;
}
}
}
}
}
cout << ans;
}
int main(void) {
cin >> K;
cin >> W >> H;
for (int i = 0; i < H; i++) {
for (int j = 0; j < W; j++) {
cin >> board[i][j];
}
}
BFS();
}
728x90