지도가 주어지면 모든 지점에 대해서 목표지점까지의 거리를 구하여라.
문제를 쉽게 만들기 위해 오직 가로와 세로로만 움직일 수 있다고 하자.
지도의 크기 n과 m이 주어진다. n은 세로의 크기, m은 가로의 크기다.(2 ≤ n ≤ 1000, 2 ≤ m ≤ 1000)
다음 n개의 줄에 m개의 숫자가 주어진다. 0은 갈 수 없는 땅이고 1은 갈 수 있는 땅, 2는 목표지점이다. 입력에서 2는 단 한개이다.
각 지점에서 목표지점까지의 거리를 출력한다. 원래 갈 수 없는 땅인 위치는 0을 출력하고, 원래 갈 수 있는 땅인 부분 중에서 도달할 수 없는 위치는 -1을 출력한다.
import java.util.*;
import java.io.*;
public class Main {
static int N, M;
static boolean[][] visited;
static int[][] arr;
static int[] dx = { -1, 1, 0, 0 };
static int[] dy = { 0, 0, 1, -1 };
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringBuilder sb = new StringBuilder();
StringTokenizer st;
st = new StringTokenizer(br.readLine());
N = Integer.parseInt(st.nextToken());
M = Integer.parseInt(st.nextToken());
arr= new int[N][M];
int x = 0;
int y = 0;
for (int i = 0; i < N; i++) {
st = new StringTokenizer(br.readLine());
for (int j = 0; j < M; j++) {
arr[i][j] = Integer.parseInt(st.nextToken());
if (arr[i][j] == 2) {
arr[i][j] = 0;
x = i;
y = j;
}
}
}
visited = new boolean[N][M];
BFS(x, y);
for (int i = 0; i < N; i++) {
for (int j = 0; j < M; j++) {
if (arr[i][j] == 1 && !visited[i][j]) {
arr[i][j] = -1;
}
sb.append(arr[i][j]+" ");
}
sb.append("\n");
}
System.out.print(sb);
}
public static void BFS(int x, int y) {
Queue<Node> q = new LinkedList<>();
q.add(new Node(x, y));
visited[x][y] = true;
while (!q.isEmpty()) {
Node n = q.poll();
for (int i = 0; i < 4; i++) {
int nx = n.x + dx[i];
int ny = n.y + dy[i];
if (nx < 0 || ny < 0 || nx >= N || ny >= M)
continue;
if (visited[nx][ny] || arr[nx][ny] == 0)
continue;
q.add(new Node(nx, ny));
visited[nx][ny] = true;
arr[nx][ny] = arr[n.x][n.y] + 1;
}
}
}
}
class Node {
int x, y;
Node(int x, int y) {
this.x = x;
this.y = y;
}
}