반응형
오늘 원래 경사로 문제를 풀려고 했는데, 며칠째 붙잡아도 못 풀겠다.
진심 이게 왜 55퍼센트 정답률이지.. 난 돌대가린가.
어쩔 수 없이 다른 문제를 찾다가 이 문제를 풀게 되었다.
키포인트는 VISIT을 3차원 배열로 구성한 것이다.
VISIT[z][x][y] : z는 말 움직임으로 움직인 횟수, x와 y는 좌표를 말한다.
이것만 활용하면 문제를 풀 수 있다.
나머지 코드 작성은 일반적인 bfs문제 코드 유형과 동일하다.
#include <iostream>
#include <queue>
using namespace std;
int MAP[201][201];
int mx1[4] = {0, 0, -1, 1}; // 일반 움직임
int my1[4] = {1, -1, 0, 0}; // 일반 움직임
int mx2[8] = {-1, -2, -2, -1, 1, 2, 2, 1}; // 말 움직임
int my2[8] = {-2, -1, 1, 2, -2, -1, 1, 2}; // 말 움직임
int VISIT[31][201][201]; // 말움직임횟수, x, y
int N, M, K;
int bfs() {
queue<pair<int, pair<int, int>>> que; // {말움직임 횟수, {x, y}}
que.push({0, {0, 0}});
VISIT[0][0][0] = 1;
while(!que.empty()) {
int c = que.front().first;
int x = que.front().second.first;
int y = que.front().second.second;
que.pop();
if(x == N - 1 && y == M - 1)
return VISIT[c][x][y] - 1; // VISIT과 DEPTH를, VISIT 하나로 활용하기위해 시작지점을 1로 초기화했기에 마지막에 뺴줌.
for(int i = 0; i < 4; i++) { // 일반 움직임
int tx = x + mx1[i];
int ty = y + my1[i];
if(tx < 0 || tx >= N || ty < 0 || ty >= M)
continue;
if(VISIT[c][tx][ty] == 0 && MAP[tx][ty] != 1) {
que.push({c, {tx, ty}});
VISIT[c][tx][ty] = VISIT[c][x][y] + 1;
}
}
if(c + 1 <= K) { // 말 움직임 가능하면
for(int i = 0; i < 8; i++) { // 일반 움직임
int tx = x + mx2[i];
int ty = y + my2[i];
if(tx < 0 || tx >= N || ty < 0 || ty >= M)
continue;
if(VISIT[c + 1][tx][ty] == 0 && MAP[tx][ty] != 1) {
que.push({c + 1, {tx, ty}});
VISIT[c + 1][tx][ty] = VISIT[c][x][y] + 1;
}
}
}
}
return -1;
}
int main() {
cin >> K >> M >> N; // 입력 순서 주의!
for(int i = 0; i < N; i++) {
for(int j = 0; j < M; j++) {
cin >> MAP[i][j];
}
}
cout << bfs() << "\n";
}
소요 시간 : 35분
반응형
'[백준]' 카테고리의 다른 글
[BaekJoon/백준] 14890 경사로 (0) | 2022.08.05 |
---|---|
[BaekJoon/백준] 5558번 Cheese (0) | 2022.08.04 |
[BaekJoon/백준] 1520번 내리막 길 (0) | 2022.08.02 |
[BaekJoon/백준] 16236번 아기 상어 (0) | 2022.08.01 |
[BaekJoon/백준] 2638번 치즈 (0) | 2022.07.31 |