ALGORITHM
백준 1600 말이 되고픈 원숭이 (Java)
공부하는_다온
2023. 5. 7. 22:10
1. 문제 링크
1600번: 말이 되고픈 원숭이
첫째 줄에 정수 K가 주어진다. 둘째 줄에 격자판의 가로길이 W, 세로길이 H가 주어진다. 그 다음 H줄에 걸쳐 W개의 숫자가 주어지는데, 0은 아무것도 없는 평지, 1은 장애물을 뜻한다. 장애물이 있
www.acmicpc.net
2. 문제 및 입출력예제
3. 문제 풀이
bfs로 탐색하는 문제이다.
K번까지 움직일 수 있다고 정해져있기 때문에 좌표에 도착했을 때 몇번째로 도착했는지까지 생각해서 visit을 3차원 배열로 했다.
말의 움직임을 따랐을 때 움직임의 횟수를 증가하고, 원숭이의 움직임인 4방탐색의 경우에는 움직임의 횟수를 그대로 둔 상태로 이동한다.
4. 코드
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Queue;
import java.io.IOException;
public class Main {
static class Point{
int x;
int y;
int k;
public Point(int x, int y, int k) {
super();
this.x = x;
this.y = y;
this.k = k;
}
}
static int[] horseX = {-2, -1, 1, 2, 2, 1, -1, -2};
static int[] horseY = {1, 2, 2, 1, -1, -2, -2, -1};
static int[] monkeyX = {1, -1, 0, 0};
static int[] monkeyY = {0, 0, 1, -1};
static int K, N, M, result;
static boolean[][] map;
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
K = Integer.parseInt(br.readLine());
String[] split = br.readLine().split(" ");
M = Integer.parseInt(split[0]);
N = Integer.parseInt(split[1]);
map = new boolean[N][M];
for(int i=0;i<N;i++) {
split = br.readLine().split(" ");
for(int j=0;j<M;j++) {
if(split[j].equals("0")) {
map[i][j] = true;
}
else {
map[i][j] = false;
}
}
}
result = 0;
bfs();
System.out.println(result);
}
private static void bfs() {
Queue<Point> queue = new ArrayDeque<>();
boolean[][][] visit = new boolean[N][M][K+1];
queue.offer(new Point(0, 0, 0));
visit[0][0][0] = true;
Point now = null;
int count=0, X=0, Y=0;
while(!queue.isEmpty()) {
int size = queue.size();
for(int i=0;i<size;i++) {
now = queue.poll();
if(now.x == N-1 && now.y==M-1) {
result = count;
return;
}
for(int hd=0;hd<8;hd++) {
X = now.x+horseX[hd];
Y = now.y+horseY[hd];
if(X<0 || X>=N || Y<0 || Y>=M || now.k+1>K || !map[X][Y] || visit[X][Y][now.k+1]) {
continue;
}
queue.offer(new Point(X, Y, now.k+1));
visit[X][Y][now.k+1] = true;
}
for(int md=0;md<4;md++) {
X = now.x+monkeyX[md];
Y = now.y+monkeyY[md];
if(X<0 || X>=N || Y<0 || Y>=M || !map[X][Y] || visit[X][Y][now.k]) {
continue;
}
queue.offer(new Point(X, Y, now.k));
visit[X][Y][now.k] = true;
}
}
count++;
}
result = -1;
}
}