使用回溯的骑士算法
Posted
技术标签:
【中文标题】使用回溯的骑士算法【英文标题】:Knight's Algorithm using Backtracking 【发布时间】:2020-12-25 06:39:57 【问题描述】:我已经使用 Backtracking 编写了这个 Knight 的问题算法,并得到了以下输出,但是无论我在哪里查找,人们的编码方式都不同,我不知道这种方式是正确还是错误,需要哪些优化?谁能在这里指导我,因为我对回溯算法还很陌生。
#include<bits/stdc++.h>
using namespace std;
bool isValid(int arr[][5], int i, int j)
return (i>=0 && j>=0 && i<5 && j<5 && arr[i][j]==0);
void knightProblem(int arr[][5], int i, int j)
static int count = 0;
if(!isValid(arr,i,j))
return;
count++;
arr[i][j]=count;
knightProblem(arr,i+2,j+1);
knightProblem(arr,i+2,j-1);
knightProblem(arr,i-2,j+1);
knightProblem(arr,i-2,j-1);
knightProblem(arr,i+1,j+2);
knightProblem(arr,i+1,j-2);
knightProblem(arr,i-1,j+2);
knightProblem(arr,i-1,j-2);
int main()
int maze[5][5] =
0, 0, 0, 0, 0,
0, 0, 0, 0, 0,
0, 0, 0, 0, 0,
0, 0, 0, 0, 0,
0, 0, 0, 0, 0
;
knightProblem(maze,0,0);
for(int i=0;i<5;i++)
for(int j=0;j<5;j++)
cout<<maze[i][j]<<" ";
cout<<"\n";
输出
1 23 18 12 24
19 13 15 7 17
22 2 9 4 11
14 20 6 16 8
25 21 3 10 5
【问题讨论】:
你的代码能产生正确的答案吗? codereview.stackexchange.com 可能更合适 了解您的代码是否按预期运行的唯一方法是测试代码。那是你的工作。我们也许可以帮助您确定测试的参数,但是“我的代码有效吗?”很难卖。 但在你的情况下,我可以肯定地说,不。对于很多编译器来说,这段代码根本不起作用。例如,Visual Studio 会发生以下情况:godbolt.org/z/eqvd6v 是的,我的代码有效,输出发布在我的代码下方。我已经尝试过崇高的文字 嗯,我用不同的编译器试了一下,编译失败。读到你想要的任何东西。但也请阅读Why should I not #include <bits/stdc++.h>? 【参考方案1】:您的代码不正确。你永远不会返回 try 另一个分支,因为你总是递增计数器。您只是按 DFS 顺序遍历所有单元格,并不能保证它会产生有效的解决方案(其中有效的 solition 表示路径,而不是 DFS 顺序)。
如何纠正算法的想法:
-
正确的解决方案需要仅使用一条路径遍历所有单元格。每当您发现无法继续,并且您还没有访问所有单元格时,您需要退后一步释放当前位置。
函数
knightProblem
必须返回一个值,指示您是否在该方向找到了解决方案。如果当前状态的所有路径都不允许您找到解决方案,则需要释放单元格并返回。
避免static int counter
。由于许多原因,这是一种不好的做法。最好在main
中分配一个变量并通过引用传递它。
最终状态(表明您已找到解决方案)是您的计数器等于棋盘的大小。
【讨论】:
以上是关于使用回溯的骑士算法的主要内容,如果未能解决你的问题,请参考以下文章