【发布时间】:2013-04-09 00:11:14
【问题描述】:
所以,简而言之,我正在研究一个骑士的巡回演出计划。如果你不知道那是什么,马就会被放在棋盘上,你必须将它移动到棋盘上的每个位置一次。我正在使用递归函数,但无法让我的回溯工作。我可以在 5x5 板上达到 22 步,但程序不会备份并尝试不同的路径。我只发布了我的代码的递归部分(抱歉它有点长)任何见解都会非常有帮助。非常感谢!
`bool findPath ( int board[][boardSize + 4], int &currRow, int &currCol, int &currMove,int boardSize )
{
int i, j;
bool foundSpot;
board[currRow][currCol] = currMove;
if ( currMove == boardSize * boardSize )
return true;
for ( i = 0; i < boardSize + 4; i++ )
{
for ( j = 0; j < boardSize + 4; j++ )
cout << setw (3) << board[i][j];
cout<<endl;
}
cout << endl;
if ( board[currRow - 2][currCol - 1] == 0 )
{
currMove += 1;
board[currRow - 2][currCol - 1] = currMove;
currRow -= 2;
currCol -= 1;
if ( findPath( board, currRow, currCol, currMove, boardSize ) )
return true;
}
if ( board[currRow - 2][currCol + 1] == 0 )
{
currMove += 1;
board[currRow - 2][currCol + 1] = currMove ;
currRow -= 2;
currCol += 1;
if ( findPath( board, currRow, currCol, currMove, boardSize ) )
return true;
}
if ( board[currRow - 1][currCol + 2] == 0 )
{
currMove += 1;
board[currRow - 1][currCol + 2] = currMove ;
currRow -= 1;
currCol += 2;
if ( findPath( board, currRow, currCol, currMove, boardSize ) )
return true;
}
if ( board[currRow + 1][currCol + 2] == 0 )
{
currMove += 1;
board[currRow + 1][currCol + 2] = currMove ;
currRow += 1;
currCol += 2;
if ( findPath( board, currRow, currCol, currMove, boardSize ) )
return true;
}
if ( board[currRow + 2][currCol + 1] == 0 )
{
currMove += 1;
board[currRow + 2][currCol + 1] = currMove ;
currRow += 2;
currCol += 1;
if ( findPath( board, currRow, currCol, currMove, boardSize ) )
return true;
}
if ( board[currRow + 2][currCol - 1] == 0 )
{
currMove += 1;
board[currRow + 2][currCol - 1] = currMove ;
currRow += 2;
currCol -= 1;
if ( findPath( board, currRow, currCol, currMove, boardSize ) )
return true;
}
if ( board[currRow + 1][currCol - 2] == 0 )
{
currMove += 1;
board[currRow + 1][currCol - 2] = currMove ;
currRow += 1;
currCol -= 2;
if ( findPath( board, currRow, currCol, currMove, boardSize ) )
return true;
}
if ( board[currRow - 1][currCol - 2] == 0 )
{
currMove += 1;
board[currRow - 1][currCol - 2] = currMove ;
currRow -= 1;
currCol -= 2;
if ( findPath( board, currRow, currCol, currMove, boardSize ) )
return true;
}
board[currRow][currCol] = 0;
currMove -= 2;
return false;
}`
【问题讨论】:
-
欢迎来到 Stack Overflow!要求人们发现代码中的错误并不是特别有效。您应该使用调试器(或添加打印语句)来隔离问题,方法是跟踪程序的进度,并将其与您期望发生的情况进行比较。一旦两者发生分歧,那么您就发现了您的问题。 (然后如果有必要,你应该构造一个minimal test-case。)
-
我不认为在每个递归块中更改 currRow 和 currCol 是一个好主意 - 这意味着下一个递归块将从错误的方格开始,您的
board[currRow][currCol] = 0;将清除最后一个递归和不是您在此级别上的步骤(设置在最顶部)。为什么要设置板并更改每个if中的行和列变量?递归调用不应该解决这个问题吗?而且我认为您不希望您的行、列、移动输入成为引用 - 而是按值传递! -
您还需要对每个
if (board[][] == 0)测试进行范围检查,以确保两个坐标都在范围内。为了避免重复自己,您可能需要构建一个移动排列数组并循环遍历它们。
标签: recursion backtracking knights-tour