Uknow's Lab.
article thumbnail

https://www.acmicpc.net/problem/7562

 

7562번: 나이트의 이동

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

www.acmicpc.net

 

난이도 : 실버 1
태그 : 그래프 이론, 그래프 탐색, 너비 우선 탐색

 

 

설명

특정 위치로 이동할 수 있는 가장 적은 횟수를 찾는 문제입니다.

bfs를 활용할 수 있겠는데요.

단순히 4방향 bfs가 아닌 나이트의 이동에 맞춘 8방향 bfs를 사용하면 될 것 같습니다.

 

 

나이트의 이동은 상,하,좌,우 중 2칸 이동하고, 수직방향으로 1칸

혹은 상하좌우 1칸 이동 후 이동방향의 대각선 방향 1칸 이동으로 볼 수 있습니다.

 

그럼, 8방향을 좌표로 나타내면 어떨까요?

 

 

 

기준점에 대해 위와 같이 나타낼 수 있습니다.

 

dfs/bfs에서 상하좌우 이동을

dx = {1,-1,0,0}

dy = {0,0,1,-1}과 같이 나타내듯이,

나이트의 이동을 아래와 같이 나타낼 수 있습니다.

 

 

 

 

이후 내용은 일반적인 bfs와 동일합니다.

 

 

 

 

소스코드

 

import java.util.*

data class Point(val x: Int, val y: Int)

fun main() = with(System.`in`.bufferedReader()) {
    val sb = StringBuilder()

    // 나이트가 이동할 수 있는 방향
    val dx = intArrayOf(-2, -1, 1, 2, 2, 1, -1, -2)
    val dy = intArrayOf(1, 2, 2, 1, -1, -2, -2, -1)

    repeat(readLine().toInt()) {
        val n = readLine().toInt()

        val startXY = readLine().split(" ").map { it.toInt() }
        val start = Point(startXY[0], startXY[1])
        val endXY = readLine().split(" ").map { it.toInt() }
        val end = Point(endXY[0], endXY[1])

        // data class를 == 로 비교하면 내부의 값이 같은지 비교 (equals와 같은 역할)
        if (start == end) {
            sb.append(0).append("\n")
            return@repeat
        }


        // 일반적인 bfs와 동일
        val visited = Array(n) { IntArray(n) }

        val q = LinkedList<Point>() as Queue<Point>
        q.offer(start)
        visited[start.x][start.y] = 1

        bfs@ while (q.isNotEmpty()) {
            val target = q.poll()

            for (i in 0 until 8) {
                val nx = target.x + dx[i]
                val ny = target.y + dy[i]

                if (nx !in 0 until n || ny !in 0 until n || visited[nx][ny] != 0) continue

                if (nx == end.x && ny == end.y) {
                    sb.append(visited[target.x][target.y]).append("\n")
                    break@bfs
                }

                visited[nx][ny] = visited[target.x][target.y] + 1
                q.offer(Point(nx, ny))
            }
        }
    }

    print(sb)
}

 

 

 

 

후기

일반적인 4방향 bfs와 달리,

조금 특이한 bfs 탐색 방법이였습니다.

profile

Uknow's Lab.

@유노 Uknow

인생은 Byte와 Double 사이 Char다. 아무말이나 해봤습니다.