我正在编写经典骑士之旅的代码,我的代码似乎主要做正确的事情,但它仍然让我“不可能”的可能的板,我无法弄清楚为什么。 (例如:对于一个包含3行,4列的表,从第1行,第3列开始,它失败了)。我在计算行和列时从索引0开始。我不认为这是正确的回溯。任何人都可以帮助指出我的错误?谢谢
import java.util.*;
public class KnightGame
{
private int rows;
private int cols;
private int [][] array;
public void initializeArray()
{
array = new int [rows][cols];
}
public boolean fill (int x, int y, int n)
{
if ( x < 0 || x >= rows || y<0 || y >= cols ) //outside of board
return false;
else if (array[x][y] != 0) //location has been visited, array element occupied
return false;
else if ( n == (rows * cols)) //have visited all locations
return true;
else
{
array[x][y] = n;
if ( fill(x+1, y-2, n+1) || fill(x-2, y+1, n+1) || fill(x+1, y+2, n+1)
|| fill(x+2, y+1, n+1) || fill(x-2, y-1, n+1) || fill(x-1, y-2, n+1) ||
fill(x-1, y+2, n+1) || fill(x+2, y-1, n+1))
return true;
else
return false;
}
}
public static void main (String [] args)
{
KnightGame game = new KnightGame();
int [] st = new int [2];
int startx, starty;
Scanner keyIn = new Scanner (System.in);
System.out.println("Enter number of rows: ");
game.rows=keyIn.nextInt();
System.out.println("Enter number of columns: ");
game.cols = keyIn.nextInt();
game.initializeArray();
System.out.println("Enter starting location: ");
for (int i=0; i<2; i++)
{
st[i] = keyIn.nextInt();
}
startx = st[0];
starty = st[1];
//testing for correct starting values
System.out.println("starting values: " + startx + " " + starty);
if (game.fill(startx, starty, 1))
{
for (int i=0; i<game.rows; i++)
{
for (int j=0; j<game.cols; j++)
{
System.out.print(game.array[i][j] + " ");
}
}
}
else
System.out.println("Board could not be completed!");
}
}
答案 0 :(得分:3)
当您回溯时,您不会清除棋盘上的方块。因此,如果你递减一条潜在的路径,失败然后尝试另一条路径,那么第一次尝试仍然会标记正方形,所以第二次尝试也会失败,即使它可能已经成功。
array[x][y] = n;
if ( fill(x+1, y-2, n+1) || fill(x-2, y+1, n+1) || fill(x+1, y+2, n+1)
|| fill(x+2, y+1, n+1) || fill(x-2, y-1, n+1) || fill(x-1, y-2, n+1) ||
fill(x-1, y+2, n+1) || fill(x+2, y-1, n+1))
return true;
else
{
array[x][y] = 0; // <- add this line
return false;
}
答案 1 :(得分:1)
问题在于,当回溯发生时,你的代码没有将位置重置为0,而下一次在另一次传递中会让人感到困惑,认为它存在,但该位置应该已经重置。以下是带有修复程序的代码段:
else
{
array[x][y] = n;
if ( fill(x+1, y-2, n+1) || fill(x-2, y+1, n+1) || fill(x+1, y+2, n+1)
|| fill(x+2, y+1, n+1) || fill(x-2, y-1, n+1) || fill(x-1, y-2, n+1) ||
fill(x-1, y+2, n+1) || fill(x+2, y-1, n+1))
return true;
else {
array[x][y] = 0;//NEED THIS LINE
return false;
}
}