📌  相关文章
📜  骑士达到目标的最小步骤|设置 1

📅  最后修改于: 2022-05-13 01:57:01.020000             🧑  作者: Mango

骑士达到目标的最小步骤|设置 1

给定一个 N x N 大小的方形棋盘,给出骑士的位置和目标的位置。我们需要找出骑士到达目标位置所需的最小步数。
例子:

In above diagram Knight takes 3 step to reach 
from (4, 5) to (1, 1) (4, 5) -> (5, 3) -> (3, 2) 
-> (1, 1)  as shown in diagram

如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程学生竞争性编程现场课程。

方法:
这个问题可以看作是未加权图中的最短路径。因此我们使用 BFS 来解决这个问题。我们尝试了骑士可以从其位置到达的所有 8 个可能位置。如果可达位置尚未访问并且在板内,我们将此状态推入队列,距离比其父状态多 1。最后我们返回目标位置的距离,当它从队列中弹出时。
下面的代码实现了用于搜索单元格的 BFS,其中每个单元格都包含它与起始节点的坐标和距离。在最坏的情况下,下面的代码访问板的所有单元格,使最坏情况的时间复杂度为 O(N^2)



C++
// C++ program to find minimum steps to reach to
// specific cell in minimum moves by Knight
#include 
using namespace std;
 
// structure for storing a cell's data
struct cell {
    int x, y;
    int dis;
    cell() {}
    cell(int x, int y, int dis)
        : x(x), y(y), dis(dis)
    {
    }
};
 
// Utility method returns true if (x, y) lies
// inside Board
bool isInside(int x, int y, int N)
{
    if (x >= 1 && x <= N && y >= 1 && y <= N)
        return true;
    return false;
}
 
// Method returns minimum step
// to reach target position
int minStepToReachTarget(
    int knightPos[], int targetPos[],
    int N)
{
    // x and y direction, where a knight can move
    int dx[] = { -2, -1, 1, 2, -2, -1, 1, 2 };
    int dy[] = { -1, -2, -2, -1, 1, 2, 2, 1 };
 
    // queue for storing states of knight in board
    queue q;
 
    // push starting position of knight with 0 distance
    q.push(cell(knightPos[0], knightPos[1], 0));
 
    cell t;
    int x, y;
    bool visit[N + 1][N + 1];
 
    // make all cell unvisited
    for (int i = 1; i <= N; i++)
        for (int j = 1; j <= N; j++)
            visit[i][j] = false;
 
    // visit starting state
    visit[knightPos[0]][knightPos[1]] = true;
 
    // loop until we have one element in queue
    while (!q.empty()) {
        t = q.front();
        q.pop();
 
        // if current cell is equal to target cell,
        // return its distance
        if (t.x == targetPos[0] && t.y == targetPos[1])
            return t.dis;
 
        // loop for all reachable states
        for (int i = 0; i < 8; i++) {
            x = t.x + dx[i];
            y = t.y + dy[i];
 
            // If reachable state is not yet visited and
            // inside board, push that state into queue
            if (isInside(x, y, N) && !visit[x][y]) {
                visit[x][y] = true;
                q.push(cell(x, y, t.dis + 1));
            }
        }
    }
}
 
// Driver code to test above methods
int main()
{
    int N = 30;
    int knightPos[] = { 1, 1 };
    int targetPos[] = { 30, 30 };
    cout << minStepToReachTarget(knightPos, targetPos, N);
    return 0;
}


Java
import java.util.*;
 
// Java program to find minimum steps to reach to
// specific cell in minimum moves by Knight
class GFG {
 
    // Class for storing a cell's data
    static class cell {
        int x, y;
        int dis;
 
        public cell(int x, int y, int dis)
        {
            this.x = x;
            this.y = y;
            this.dis = dis;
        }
    }
 
    // Utility method returns true if (x, y) lies
    // inside Board
    static boolean isInside(int x, int y, int N)
    {
        if (x >= 1 && x <= N && y >= 1 && y <= N)
            return true;
        return false;
    }
 
    // Method returns minimum step
    // to reach target position
    static int minStepToReachTarget(
        int knightPos[], int targetPos[],
        int N)
    {
        // x and y direction, where a knight can move
        int dx[] = { -2, -1, 1, 2, -2, -1, 1, 2 };
        int dy[] = { -1, -2, -2, -1, 1, 2, 2, 1 };
 
        // queue for storing states of knight in board
        Vector q = new Vector<>();
 
        // push starting position of knight with 0 distance
        q.add(new cell(knightPos[0], knightPos[1], 0));
 
        cell t;
        int x, y;
        boolean visit[][] = new boolean[N + 1][N + 1];
 
        // make all cell unvisited
        for (int i = 1; i <= N; i++)
            for (int j = 1; j <= N; j++)
                visit[i][j] = false;
 
        // visit starting state
        visit[knightPos[0]][knightPos[1]] = true;
 
        // loop until we have one element in queue
        while (!q.isEmpty()) {
            t = q.firstElement();
            q.remove(0);
 
            // if current cell is equal to target cell,
            // return its distance
            if (t.x == targetPos[0] && t.y == targetPos[1])
                return t.dis;
 
            // loop for all reachable states
            for (int i = 0; i < 8; i++) {
                x = t.x + dx[i];
                y = t.y + dy[i];
 
                // If reachable state is not yet visited and
                // inside board, push that state into queue
                if (isInside(x, y, N) && !visit[x][y]) {
                    visit[x][y] = true;
                    q.add(new cell(x, y, t.dis + 1));
                }
            }
        }
        return Integer.MAX_VALUE;
    }
 
    // Driver code
    public static void main(String[] args)
    {
        int N = 30;
        int knightPos[] = { 1, 1 };
        int targetPos[] = { 30, 30 };
        System.out.println(
            minStepToReachTarget(
                knightPos, targetPos, N));
    }
}
 
// This code contributed by Rajput-Ji


Python3
# Python3 code to find minimum steps to reach
# to specific cell in minimum moves by Knight
class cell:
     
    def __init__(self, x = 0, y = 0, dist = 0):
        self.x = x
        self.y = y
        self.dist = dist
         
# checks whether given position is
# inside the board
def isInside(x, y, N):
    if (x >= 1 and x <= N and
        y >= 1 and y <= N):
        return True
    return False
     
# Method returns minimum step to reach
# target position
def minStepToReachTarget(knightpos,
                         targetpos, N):
     
    # all possible movments for the knight
    dx = [2, 2, -2, -2, 1, 1, -1, -1]
    dy = [1, -1, 1, -1, 2, -2, 2, -2]
     
    queue = []
     
    # push starting position of knight
    # with 0 distance
    queue.append(cell(knightpos[0], knightpos[1], 0))
     
    # make all cell unvisited
    visited = [[False for i in range(N + 1)]
                      for j in range(N + 1)]
     
    # visit starting state
    visited[knightpos[0]][knightpos[1]] = True
     
    # loop until we have one element in queue
    while(len(queue) > 0):
         
        t = queue[0]
        queue.pop(0)
         
        # if current cell is equal to target
        # cell, return its distance
        if(t.x == targetpos[0] and
           t.y == targetpos[1]):
            return t.dist
             
        # iterate for all reachable states
        for i in range(8):
             
            x = t.x + dx[i]
            y = t.y + dy[i]
             
            if(isInside(x, y, N) and not visited[x][y]):
                visited[x][y] = True
                queue.append(cell(x, y, t.dist + 1))
 
# Driver Code    
if __name__=='__main__':
    N = 30
    knightpos = [1, 1]
    targetpos = [30, 30]
    print(minStepToReachTarget(knightpos,
                               targetpos, N))
     
# This code is contributed by
# Kaustav kumar Chanda


C#
// C# program to find minimum steps to reach to
// specific cell in minimum moves by Knight
using System;
using System.Collections.Generic;
 
class GFG {
 
    // Class for storing a cell's data
    public class cell {
        public int x, y;
        public int dis;
 
        public cell(int x, int y, int dis)
        {
            this.x = x;
            this.y = y;
            this.dis = dis;
        }
    }
 
    // Utility method returns true
    // if (x, y) lies inside Board
    static bool isInside(int x, int y, int N)
    {
        if (x >= 1 && x <= N && y >= 1 && y <= N)
            return true;
        return false;
    }
 
    // Method returns minimum step
    // to reach target position
    static int minStepToReachTarget(int[] knightPos,
                                    int[] targetPos, int N)
    {
        // x and y direction, where a knight can move
        int[] dx = { -2, -1, 1, 2, -2, -1, 1, 2 };
        int[] dy = { -1, -2, -2, -1, 1, 2, 2, 1 };
 
        // queue for storing states of knight in board
        Queue q = new Queue();
 
        // push starting position of knight with 0 distance
        q.Enqueue(new cell(knightPos[0],
                           knightPos[1], 0));
 
        cell t;
        int x, y;
        bool[, ] visit = new bool[N + 1, N + 1];
 
        // make all cell unvisited
        for (int i = 1; i <= N; i++)
            for (int j = 1; j <= N; j++)
                visit[i, j] = false;
 
        // visit starting state
        visit[knightPos[0], knightPos[1]] = true;
 
        // loop until we have one element in queue
        while (q.Count != 0) {
            t = q.Peek();
            q.Dequeue();
 
            // if current cell is equal to target cell,
            // return its distance
            if (t.x == targetPos[0] && t.y == targetPos[1])
                return t.dis;
 
            // loop for all reachable states
            for (int i = 0; i < 8; i++) {
                x = t.x + dx[i];
                y = t.y + dy[i];
 
                // If reachable state is not yet visited and
                // inside board, push that state into queue
                if (isInside(x, y, N) && !visit[x, y]) {
                    visit[x, y] = true;
                    q.Enqueue(new cell(x, y, t.dis + 1));
                }
            }
        }
        return int.MaxValue;
    }
 
    // Driver code
    public static void Main(String[] args)
    {
        int N = 30;
        int[] knightPos = { 1, 1 };
        int[] targetPos = { 30, 30 };
        Console.WriteLine(
            minStepToReachTarget(
                knightPos,
                targetPos, N));
    }
}
// This code is contributed by 29AjayKumar


Javascript


输出:

20

复杂度分析:

  • 时间复杂度: O(N^2)。
    在最坏的情况下,将访问所有单元格,因此时间复杂度为 O(N^2)。
  • 辅助空间: O(N^2)。
    节点存储在队列中。所以空间复杂度是 O(N^2)。