|
| 1 | +import java.util.*; |
| 2 | + |
| 3 | +/** |
| 4 | + * 알고리즘: bfs |
| 5 | + * 시간복잡도: 1 ≤ N ≤ 500 체스판의 크기는 N*N 으로 최대 2500. O(N^2)까지 가능 |
| 6 | + * 아이디어: |
| 7 | + * 나이트(K)는 8방향으로 움직일 수 있고, 말을 잡기 위한 최단거리를 구하는 문제 > BFS 알고리즘 |
| 8 | + * 각 8방향을 움직이는데, 현재 위치 ~ 다음 위치까지 `이동한 거리를 각 위치마다 저장` `체스판에도 이동거리 저장` |
| 9 | + * 체스판의 위치마다 이동한 거리를 계속해서 누적해서 저장하기 때문에 적(E)이 있는 위치가 최단거리가 됨 |
| 10 | + */ |
| 11 | +public class YJ_18404 { |
| 12 | + static class Knight{ |
| 13 | + int x; |
| 14 | + int y; |
| 15 | + int distance; |
| 16 | + Knight(int x, int y, int distance){ |
| 17 | + this.x = x; |
| 18 | + this.y = y; |
| 19 | + this.distance = distance; |
| 20 | + } |
| 21 | + } |
| 22 | + |
| 23 | + static Queue<Knight> queue = new LinkedList<>(); |
| 24 | + static int[][] MOVEMENTS = {{-2,-1},{-2,1},{-1,-2},{-1,2},{1,-2},{1,2},{2,-1},{2,1}}; |
| 25 | + static void findMinMoveCount(int[][] chessBoard, boolean[][] visited) { |
| 26 | + while(!queue.isEmpty()){ |
| 27 | + Knight knight = queue.poll(); |
| 28 | + |
| 29 | + for(int[] move : MOVEMENTS){ |
| 30 | + int nextX = knight.x + move[0]; |
| 31 | + int nextY = knight.y + move[1]; |
| 32 | + |
| 33 | + //이동할 위치에 나이트가 갈 수 없다면 해당 구간 탐색 x |
| 34 | + if(nextX<1 || nextX >= chessBoard.length || nextY<1 || nextY >= chessBoard.length || visited[nextX][nextY]){ |
| 35 | + continue; |
| 36 | + } |
| 37 | + |
| 38 | + visited[nextX][nextY] = true; |
| 39 | + //다음 위치로 갈 나이트에게 현재 위치~다음 위치까지의 이동거리 누적 저장 |
| 40 | + int distance = knight.distance + 1; |
| 41 | + queue.offer(new Knight(nextX, nextY, distance)); |
| 42 | + chessBoard[nextX][nextY] = distance; |
| 43 | + } |
| 44 | + } |
| 45 | + } |
| 46 | + |
| 47 | + public static void main(String[] args) { |
| 48 | + Scanner sc = new Scanner(System.in);; |
| 49 | + //NxN:체스판, M:말 갯수 |
| 50 | + String[] first = sc.nextLine().split(" "); |
| 51 | + int N = Integer.parseInt(first[0]); |
| 52 | + int M = Integer.parseInt(first[1]); |
| 53 | + |
| 54 | + int[][] chessBoard = new int[N+1][N+1]; |
| 55 | + boolean[][] visited = new boolean[N+1][N+1]; |
| 56 | + |
| 57 | + //나이트위치 |
| 58 | + String[] second = sc.nextLine().split(" "); |
| 59 | + int x =Integer.parseInt(second[0]); |
| 60 | + int y =Integer.parseInt(second[1]); |
| 61 | + queue.offer(new Knight(x,y,0)); |
| 62 | + visited[x][y] = true; |
| 63 | + |
| 64 | + //말들 위치 저장 |
| 65 | + List<int[]> enemys = new ArrayList<>(); |
| 66 | + for(int i=0; i<M; i++){ |
| 67 | + String[] line = sc.nextLine().split(" "); |
| 68 | + int enemyX = Integer.parseInt(line[0]); |
| 69 | + int enemyY = Integer.parseInt(line[1]); |
| 70 | + enemys.add(new int[]{enemyX,enemyY}); |
| 71 | + } |
| 72 | + |
| 73 | + findMinMoveCount(chessBoard, visited); |
| 74 | + for(int[] e : enemys){ |
| 75 | + System.out.print(chessBoard[e[0]][e[1]] + " "); |
| 76 | + } |
| 77 | + } |
| 78 | +} |
0 commit comments