코딩테스트/백준_Java
Q. 18404 자바 : 현명한 나이트
Ski_
2023. 4. 11. 09:21
Q. 18404 자바 : 현명한 나이트
문제 : boj.kr/18404
실버 1 난이도의 문제이다. 앞의 나이트의 이동 문제와 비슷하다.
나이트의 위치가 주어지고, 잡아야 할 말의 위치가 여러 개 주어진다.
이 때 각각의 말을 나이트가 몇 번 움직여서 말을 잡을수 있는지 출력하는 문제이다.
격자형 그래프 탐색문제에서 상 하 좌 우 순회하는 방식을 응용해탐색하는 범위만 바꾸면 쉽게 풀리는 문제이다.
체스판의 한 변의 길이로 주어지는 N의 최대값이 500이고,
잡아야 할 말의 수 M의 최대값이 1000이다. 따라서 시간복잡도는 아래와 같다.
1. 주어진 말의 수 - O(M)
2. BFS 순회 - O(N ^ 2)
시간복잡도는 약 O(N ^ 2)이고, 최대 2500000번 계산을 하면 문제를 해결할 수 있다.
따라서 시간초과는 걱정하지 않아도 된다.
또한 자료형 역시 int 범위 내에서 모두 해결할 수 있다.
풀이는 아래와 같다.
import java.io.*;
import java.util.*;
public class Main {
static FastReader scan = new FastReader();
static StringBuilder sb = new StringBuilder();
static int M, N;
static int[][] dist;
static int curX, curY;
static int[][] goal;
static int[] dy = {1, 1, 2, 2, -1, -1, -2, -2};
static int[] dx = {2, -2, 1, -1, 2, -2, 1, -1};
static void input() {
N = scan.nextInt();
M = scan.nextInt();
curX = scan.nextInt();
curY = scan.nextInt();
dist = new int[N + 1][N + 1];
goal = new int[M][2];
for (int i = 0; i < M; i++) {
goal[i][0] = scan.nextInt();
goal[i][1] = scan.nextInt();
}
}
static void bfs() {
Queue<int[]> que = new LinkedList<>();
que.add(new int[]{curY, curX});
dist[curY][curX] = 1;
while (!que.isEmpty()) {
int[] cur = que.poll();
for (int i = 0; i < 8; i++) {
int ny = cur[0] + dy[i];
int nx = cur[1] + dx[i];
if (ny <= 0 || nx <= 0 || ny > N || nx > N) continue;
if (dist[ny][nx] != 0) continue;
que.add(new int[] {ny, nx});
dist[ny][nx] = dist[cur[0]][cur[1]] + 1;
}
}
}
static void pro() {
bfs();
for (int i = 0; i < M; i++)
sb.append(dist[goal[i][1]][goal[i][0]] - 1).append(' ');
System.out.println(sb);
}
public static void main(String[] args) {
input();
pro();
}
static class FastReader {
// BufferedReader의 빠른 속도,
// + Scanner의 타입별 입력값을 받는 기능을 혼합
// (자바 내부에 구현된 Scanner는 속도가 느림)
// 다른분의 코드를 참고한 코드
BufferedReader br;
StringTokenizer st;
public FastReader() {
br = new BufferedReader(new InputStreamReader(System.in));
}
public FastReader(String s) throws FileNotFoundException {
br = new BufferedReader(new FileReader(new File(s)));
}
String next() {
while (st == null || !st.hasMoreElements()) {
try {
st = new StringTokenizer(br.readLine());
} catch (IOException e) {
e.printStackTrace();
}
}
return st.nextToken();
}
int nextInt() {
return Integer.parseInt(next());
}
long nextLong() {
return Long.parseLong(next());
}
double nextDouble() {
return Double.parseDouble(next());
}
String nextLine() {
String str = "";
try {
str = br.readLine();
} catch (IOException e) {
e.printStackTrace();
}
return str;
}
}
}
반응형