[백준][7652:나이트의 이동 ][JAVA]

Boknami·2023년 9월 13일
0

백준문제풀이

목록 보기
34/45

체스판 위에 한 나이트가 놓여져 있다. 나이트가 한 번에 이동할 수 있는 칸은 아래 그림에 나와있다. 나이트가 이동하려고 하는 칸이 주어진다. 나이트는 몇 번 움직이면 이 칸으로 이동할 수 있을까?

고민이었던 부분

전체적 코드를 작성하는데 있어서는 크게 어렵지 않았다.
반복문을 돌며 8방향 탐색을 하며 우리가 원하는 값이 나올때까지 BFS진행

그런데 정..말 엄청 고민한 부분이있다. 매우 부끄러운 수준이지만


//움직였을 때 종료 조건이 만족한다면 종료!
if(moveX == eX && moveY == eY){
      visited[moveX][moveY] = visited[earlyX][earlyY]+1;
      break;
}
//방문할 수 있는 걸 모두 방문하지 않고 종료되서? 아닌데 bfs는 칸수에 따라서 실행되는거아냐?
//아니 여기서 종료를 하면 for문만 종료되잖아 바보여 ㅠㅠㅠㅠㅠ

8방향 탐색 안에 이 부분이 있었다.
탐색을 하다가 우리가 원하는 부분을 찾으면 그 때는 값을 저장하고 break하려고 했다.

엄청나게 바보짓을 했다.
while반복문 속에 for반복문이 있는데 당연히 for안에서 break를 하면 for가 종료된다.
이미 발견한 정답을 제치고 다시 반복문을 계속 돌며 값을 찾는 것이다.

말도 안되는 부분이지만 이 잘못된 부분을 찾는데 상당한 시간을 소요했다..정말 잘못 꼳히면 끝도 없는 것 같다.

해결

 //움직였을 때 종료 조건이 만족한다면 종료!
if(moveX == eX && moveY == eY)
    return visited[earlyX][earlyY]+1;

정답 코드

import java.io.*;
import java.util.*;

public class Main {
    static int[][] board;
    static int[][] visited;
    static int line;
    public static void main(String args[]) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer st = new StringTokenizer(br.readLine());

        int repeat = Integer.parseInt(st.nextToken());

        for(int i = 0 ; i < repeat; i++){
            st = new StringTokenizer(br.readLine());
            line = Integer.parseInt(st.nextToken());

            st = new StringTokenizer(br.readLine());
            int sX = Integer.parseInt(st.nextToken());
            int sY= Integer.parseInt(st.nextToken());

            st = new StringTokenizer(br.readLine());
            int eX = Integer.parseInt(st.nextToken());
            int eY= Integer.parseInt(st.nextToken());

            System.out.println(BFS(sX, sY, eX, eY));
        }
    }

    private static int BFS(int sX, int sY, int eX, int eY) {
        board = new int[line][line];
        visited = new int[line][line];

        Queue<int[]> queue = new LinkedList<>();
        queue.add(new int[]{sX,sY});

        int[] dx = {-2,-1,1,2,2,1,-1,-2};
        int[] dy = {1,2,2,1,-1,-2,-2,-1};

        while (!queue.isEmpty()){
            int[] q_remove = queue.poll();
            int earlyX = q_remove[0];
            int earlyY = q_remove[1];

            if(earlyX == eX && earlyY == eY){
                visited[earlyX][earlyY] = visited[earlyX][earlyY];
                break;
            }

            for(int i = 0 ; i < 8; i++){
                int moveX = earlyX + dx[i];
                int moveY = earlyY + dy[i];

                //움직였을 때 종료 조건이 만족한다면 종료!
                if(moveX == eX && moveY == eY)
                    return visited[earlyX][earlyY]+1;

                //방문할 수 있는 걸 모두 방문하지 않고 종료되서? 아닌데 bfs는 칸수에 따라서 실행되는거아냐?
                //하 아니 여기서 종료를 하면 for문만 종료되잖아 바보여 ㅠㅠㅠㅠㅠ

                if(moveX < line && moveX >= 0 && moveY < line && moveY >= 0){
                    if(visited[moveX][moveY] == 0){
                        queue.add(new int[]{moveX,moveY});
                        visited[moveX][moveY] = visited[earlyX][earlyY]+1;
                    }
                }
            }
        }

        return 0;
    }
}

0개의 댓글