java 骑士之旅(递归)
Knight's tour in java (recursive)
我正在为经典骑士之旅编写代码,我的代码似乎大部分都在做正确的事情,但它仍然为我提供了 "not possible" 可能的板,但我不明白为什么。 (例如:对于具有 3 行 4 列的 table,从第 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!");
}
}
你原路返回时并没有清除棋盘上的方块。因此,如果您沿着一条可能的路径递归,失败然后尝试另一条路径,则方块仍会从第一次尝试中标记出来,因此第二次尝试也会失败,即使这可能是可能的。
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;
}
问题是,当回溯发生时,您的代码没有将位置重置为 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;
}
}
我正在为经典骑士之旅编写代码,我的代码似乎大部分都在做正确的事情,但它仍然为我提供了 "not possible" 可能的板,但我不明白为什么。 (例如:对于具有 3 行 4 列的 table,从第 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!");
}
}
你原路返回时并没有清除棋盘上的方块。因此,如果您沿着一条可能的路径递归,失败然后尝试另一条路径,则方块仍会从第一次尝试中标记出来,因此第二次尝试也会失败,即使这可能是可能的。
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;
}
问题是,当回溯发生时,您的代码没有将位置重置为 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;
}
}