C# N皇后算法。情节转折:女王也是一名骑士
试图在C# N皇后算法。情节转折:女王也是一名骑士,c#,algorithm,recursion,C#,Algorithm,Recursion,试图在N*N板上修改骑士移动集的N皇后算法。在我的例子中,我在4*4和8*8板上测试它 我的算法,resp。我的递归无法处理骑士,因为它有时需要跳过一行。如果只是皇后的移动,则不需要跳过行,因为每行正好有1个Queen 问题出在我的Solve()函数中,因为我的递归与皇后数有关。通常情况下,每个板上的皇后数应为8。然而,加入骑士的移动会将数量减少到6。因此,我认为递归不够深入(只有6行深,而不是8行深) 例如,4*4板上的解决方案是(1,1)和(4,2)(行*列)。但它不能跳过第2行和第3行 如
N*N
板上修改骑士移动集的N皇后
算法。在我的例子中,我在4*4
和8*8
板上测试它
我的算法,resp。我的递归无法处理骑士,因为它有时需要跳过一行。如果只是皇后的移动,则不需要跳过行,因为每行正好有1个Queen
问题出在我的Solve()
函数中,因为我的递归与皇后数有关。通常情况下,每个板上的皇后数应为8
。然而,加入骑士的移动会将数量减少到6
。因此,我认为递归不够深入(只有6行深,而不是8行深)
例如,4*4
板上的解决方案是(1,1)
和(4,2)
(行*列)。但它不能跳过第2行和第3行
如何使递归遍历所有行,同时能够跳过一些行
static int[]board=new int[9];
静态int cnt=0;
静态布尔CanPlace(int行,int列)//例如x[1]=2,第1行第2列有一个皇后
{
对于(int j=1;j是的,这会变得更加困难。您需要对前面的问题进行一些修改,这使它成为一个有价值的编程练习
记下你放了多少皇后
允许跳过一行:不放置皇后不是失败;您只是不更新计数
您需要保留到目前为止找到的最佳解决方案(最大数量的皇后),并继续运行,直到第一个皇后跑过中间点
请注意,您不必在第一行中不允许有皇后。如果有一个解决方案在第一行中没有皇后,则有一个对应的解决方案,皇后数量相同,仅移动一行
这足以让您继续前进吗?是的,这会变得更困难。您需要对前面的问题进行一些修改,这使得这是一个有价值的编程练习
记下你放了多少皇后
允许跳过一行:不放置皇后不是失败;您只是不更新计数
您需要保留到目前为止找到的最佳解决方案(最大数量的皇后),并继续运行,直到第一个皇后跑过中间点
请注意,您不必在第一行中不允许有皇后。如果有一个解决方案在第一行中没有皇后,则有一个对应的解决方案,皇后数量相同,仅移动一行
这足以让你行动起来吗?我认为第一步是证明一个解决方案exists@Steve--当返回的计数为0时会发生这种情况。不过,这不是一种残酷的力量吗…原始n皇后的解决方案是greedy我们确实需要一个穷举搜索:贪婪算法不一定会产生一个最优解。有时,我们必须留下一个中间的空白行。我也注意到轻微的心理错误:永远不会有0的返回值。你总是可以放置至少一个皇后。我认为第一步是证明一个解决方案。exists@Steve--当返回的计数为0时会发生这种情况。但是,这不是一种残酷的力量吗?原始n皇后的解决方案是格里迪。我们确实需要一个彻底的西尔CH:贪婪算法不一定产生最佳的解决方案。有时候,我们必须在中间留一个空行。我也注意到轻微的心理错误:永远不会有0的返回值。你总是可以放置至少一个皇后。
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);
}