骑士达到目标的最小步骤|设置 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)。