1

我正在为经典的骑士之旅编写代码,我的代码似乎大部分都在做正确的事情,但它仍然让我对可能的董事会“不可能”,我不知道为什么。(例如:对于从第 1 行第 3 列开始的 3 行 4 列的表,它失败了)。计算行和列时,我从索引 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!");

    }

}
4

2 回答 2

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; 
        }
于 2015-03-13T04:48:56.353 回答
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; 
    }              
}
于 2015-03-13T04:51:32.033 回答