尝试在N-Queens
板上修改骑士运动集的N*N
算法。在我的情况下,我在4*4
和8*8
板上测试它。
我的算法,分别是我的递归无法处理Knight,因为它有时需要跳过一行。如果它只是一个皇后区的动作,则不需要跳过行,因为每行只有1
皇后。
问题出在我的Solve()
函数中,因为我的递归与Queens的数量有关。通常,每块板的皇后数应为8
。但是,结合骑士的动作会将数量减少到6
。因此,我认为,递归不够深(只有6行,而不是8行)。
例如,4*4
电路板上的解决方案是(1,1)
和(4,2)
(行* col)。但它无法跳过第2和第3行。
如何在能够跳过某些行的同时使递归遍历所有行。
static int[] board = new int[9];
static int cnt = 0;
static bool CanPlace(int row, int col) // eg. x[1] = 2, 1st row 2nd col has a Queen
{
for (int j = 1; j <= (row - 1); j++)
{
if (board[j] == col || Math.Abs(board[j] - col) == Math.Abs(j - row)) return false;
if ((Math.Abs(board[j] - col) - 1) == Math.Abs(j - row)) return false;
//The line of code above should work for all of the possible moves of the Knight.
//At least it does for a 4x4 board, for the first two lines.
//Giving a pair of results = (1,1)(2,4) and the mirror (1,4)(2,1)
}
return true;
}
static void Solve(int row, int boardSize)
{
for (int col = 1; col <= boardSize; col++)
{
if (CanPlace(row, col)) //This only triggers 6 times per board
{
board[row] = col;
if (row == boardSize - 2) // Here i tried to fix it but the bottom rows get sacrificed
PrintBoard();
else
Solve(row + 1, boardSize);
}
}
}
static void PrintBoard()
{
Console.WriteLine();
cnt++;
for (int i = 1; i <= board.Length-1; i++)
{
for (int j = 1; j <= board.Length - 1; j++)
if (board[i] == j) Console.Write("Q");
else Console.Write(".");
Console.WriteLine();
}
for (int i = 1; i <= board.Length - 1; i++)
Console.Write("{0},", board[i]);
Console.WriteLine();
}
static void Main(string[] args)
{
Solve(1, 8);
Console.WriteLine("\nNumber of solutions: {0}\n",cnt);
}
答案 0 :(得分:0)
是的,这变得更难了。您需要对早期问题进行一些修改,这使得这是一个值得编程的练习。
请注意,不必须允许第一行中没有女王。如果在第一行中有一个没有任何皇后的解决方案,那么有一个相应的解决方案,只有一个皇后,只移动了一行。
这足以让你感动吗?