본문 바로가기
algorithm

[JAVA] 백준 7562 - 나이트의 이동 ( BFS)

by onejunu 2021. 2. 18.

www.acmicpc.net/problem/7562

 

7562번: 나이트의 이동

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

www.acmicpc.net

 

 

-이동할 방향 코드 작성

이동 방향

 

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

 

10시 방향부터 시계방향으로 8가지 위치를 지정한 것이다.

 

예를 들어, 기존의 위치가 (x,y) = (10,10)  이라고 가정하자. 

 

( x + dx[0] , y + dy[0] ) = 10시방향 좌표

( x + dx[1] , y + dy[1] ) = 11시방향 좌표

( x + dx[2] , y + dy[2] ) = 1시방향 좌표

...

 

 

- BFS 적용하기 

 

방문 체크를 하기 위한 배열로 visited 를 선언하고 301 * 301 크기로 지정한다.

보통 boolean 타입으로 지정하지만 출발지에서 목적지까지 몇번 이동했는지 체크해야 되므로 거리 측정겸 방문체크를 동시에 하기위해 아래처럼 선언하였다.

 

    static int[][] visited = new int[301][301];

 

그리고 배열의 초기값을 모두 -1로 초기화 하였다.

 

public static void cleanVisited(){
        for(int i=0;i<=300;i++)
            for(int j=0;j<=300;j++)
                visited[i][j]=-1;
    }

 

처음 출발지의 좌표를 x1,y1 이라고 할 때 visited[x1][y1] = 0 으로 초기화한다. 

 

x1 ,y1 에서 다음 으로 이동할 8개 경우의 수가 있다. 이 중에서 하나를 nx,ny 라고 하자.

visited[nx][ny] < visited[x1][y1] + 1 이거나 방문한적이 없다면 방문하도록 한다.

 

public static void bfs(int a,int b,int c,int d){

        Queue<Point> q = new LinkedList<>();
        q.add(new Point(a,b));
        visited[a][b] = 0;

        while(!q.isEmpty()){
            Point p = q.poll();

            if(p.x == c && p.y == d) break;

            for(int i=0;i<8;i++){
                int nx = p.x + dx[i];
                int ny = p.y + dy[i];

                if(0<=nx && nx<n && 0<=ny & ny<n &&
                        (visited[nx][ny]==-1 || visited[p.x][p.y]+1 < visited[nx][ny])
                ){
                    visited[nx][ny] = visited[p.x][p.y]+1;
                    q.add(new Point(nx,ny));
                }
            }


        }

    }

 

- 전체코드

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.*;

public class Main {

    static int tt;
    static int n;
    static int x1,y1;
    static int x2,y2;

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

    static int[][] visited = new int[301][301];

    public static void main(String[] args) throws Exception {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer st = new StringTokenizer(br.readLine());
        tt = Integer.parseInt(st.nextToken());

        while(tt--!=0){
            st = new StringTokenizer(br.readLine());
            n = Integer.parseInt(st.nextToken());

            st = new StringTokenizer(br.readLine());
            x1 = Integer.parseInt(st.nextToken());
            y1 = Integer.parseInt(st.nextToken());

            st = new StringTokenizer(br.readLine());
            x2 = Integer.parseInt(st.nextToken());
            y2 = Integer.parseInt(st.nextToken());

            cleanVisited();


            bfs(x1,y1,x2,y2);

            System.out.println(visited[x2][y2]);
        }

    }

    public static void bfs(int a,int b,int c,int d){

        Queue<Point> q = new LinkedList<>();
        q.add(new Point(a,b));
        visited[a][b] = 0;

        while(!q.isEmpty()){
            Point p = q.poll();

            if(p.x == c && p.y == d) break;

            for(int i=0;i<8;i++){
                int nx = p.x + dx[i];
                int ny = p.y + dy[i];

                if(0<=nx && nx<n && 0<=ny & ny<n &&
                        (visited[nx][ny]==-1 || visited[p.x][p.y]+1 < visited[nx][ny])
                ){
                    visited[nx][ny] = visited[p.x][p.y]+1;
                    q.add(new Point(nx,ny));
                }
            }


        }

    }

    public static void cleanVisited(){
        for(int i=0;i<=300;i++)
            for(int j=0;j<=300;j++)
                visited[i][j]=-1;
    }

    static class Point{
        int x,y;

        public Point(int x, int y) {
            this.x = x;
            this.y = y;
        }
    }

}

댓글