https://www.acmicpc.net/problem/1600
1600번: 말이 되고픈 원숭이
첫째 줄에 정수 K가 주어진다. 둘째 줄에 격자판의 가로길이 W, 세로길이 H가 주어진다. 그 다음 H줄에 걸쳐 W개의 숫자가 주어지는데, 0은 아무것도 없는 평지, 1은 장애물을 뜻한다. 장애물이 있
www.acmicpc.net
1. 문제설명
일반적인 BFS문제는 상하좌우로 네칸만 움직인다.
이 문제는 원숭이가 평소에는 상하좌우로 네칸을 움직일 수 있다가
K번의 기회로 말처럼 더 넓은 범위를 움직일 수 있다.
이런 문제를 표현하기 위해서는 최대 K번 말처럼 움직일 수 있으므로
현재까지 원숭이가 총 몇 번 말처럼 움직였는지 상태를 저장해줄 필요가 있다.
그래서 이러한 문제 유형을 나는 상태 추가 BFS라고 부르기로 했다.
그냥 저 혼자 부르는 거니까 다른데 가서 유식한 척 말하시면 안됩니다.
2. 상태추가?
왜 상태추가라고 하냐면
보통 일반적으로 BFS를 돌 때는
x,y 좌표를 방문했는지 여부를 저장하면서 중복된 행동을 하지 않도록 합니다.
이 문제도 단지 x,y좌표를 방문했는지 여부와 동일하게
x,y좌표 방문 여부 + '말처럼 움직인 횟수' 라는 상태가 추가되어
중복된 행동을 하지 않으면서 BFS를 돈다고 생각하면 편합니다.
그리고 또한 이 문제를 왜 BFS로 해결 할 수 있냐면
원하는 답이 원숭이가 총 몇번 움직이는 행동을 했는 지 구하는 것이기 때문에
말처럼 움직이든 원숭이처럼 움직이든 특정 행동엔 관심없고
움직임 단계별로 일정하게 증가시키면서 답을 구하면 되기 때문에
너비우선탐색으로 해결 할 수 있습니다.
3.문제풀이코드 C++
#include <bits/stdc++.h>
using namespace std;
struct Position {
int x, y, k, d;
Position(int a, int b, int c, int dd) {
x = a, y = b, k = c, d = dd;
}
};
int dx[4] = {1, 0, -1, 0};
int dy[4] = {0, 1, 0, -1};
//horse
int hdx[8] = {-2, -2, -1, -1, 1, 1, 2, 2};
int hdy[8] = {-1, 1, -2, 2, -2, 2, -1, 1};
queue<Position> Q;
int K, W, H;
int arr[203][203];
bool vis[203][203][32];
int main() {
ios::sync_with_stdio(0);
cin.tie(0);
cin >> K >> W >> H;
// 행H , 열W
for (int i = 0; i < H; i++) {
for (int j = 0; j < W; j++) {
cin >> arr[i][j];
}
}
Q.push({0, 0, 0, 0});
while (!Q.empty()) {
auto cur = Q.front();
Q.pop();
if (cur.x == H - 1 && cur.y == W - 1) {
cout << cur.d << '\n';
return 0;
}
for (int i = 0; i < 4; i++) {
int nx = cur.x + dx[i];
int ny = cur.y + dy[i];
if (nx < 0 || nx >= H || ny < 0 || ny >= W) continue;
if (vis[nx][ny][cur.k] || arr[nx][ny] == 1) continue;
vis[nx][ny][cur.k] = 1;
Q.push({nx, ny, cur.k, cur.d + 1});
}
if (cur.k + 1 <= K) {
for (int i = 0; i < 8; i++) {
int nx = cur.x + hdx[i];
int ny = cur.y + hdy[i];
if (nx < 0 || nx >= H || ny < 0 || ny >= W) continue;
if (vis[nx][ny][cur.k + 1] || arr[nx][ny] == 1) continue;
vis[nx][ny][cur.k + 1] = 1;
Q.push({nx, ny, cur.k + 1, cur.d + 1});
}
}
}
cout << -1 << '\n';
return 0;
}
'Algorithm > problem' 카테고리의 다른 글
백준 14226번 : 이모티콘 - BFS (0) | 2022.07.02 |
---|---|
[백준] 1963번 : 소수경로 - 에라토스테네스의 체, BFS (0) | 2022.07.02 |
백준 1325번 : 효율적인 해킹 -BFS, DP를 쓰면 안되는 이유 C++ (0) | 2022.07.02 |
백준 16563번 : 어려운 소인수분해 - 에라토스테네스의 체 C++ (0) | 2022.06.29 |
백준 2470번 : 두 용액 - 투포인터 (0) | 2022.06.29 |