【发布时间】:2020-08-03 01:33:34
【问题描述】:
我自己解决了 N 个皇后问题,并采用了解决方案和在线中提到的不同方法。
我的代码适用于最多 4 的输入,但开始打印 4 之后的任何值的每个案例(即使是错误的)。我已经检查了很多次,但我无法在代码。
PFA 代码,看看你是否能找到错误。 谢谢!
import java.io.*;
import java.util.*;
public class Main {
public static void main(String[] args) throws Exception {
Scanner scn = new Scanner(System.in);
int n= scn.nextInt();
int[][] arr = new int[n][n];
printNQueens(arr,"",0);
System.out.println();
}
public static void printNQueens(int[][] chess, String qsf, int row) {
if(row==chess.length)
{
qsf = qsf + ".";
System.out.println(qsf);
return;
}
for(int j=0;j<chess[0].length;j++)
{
if(chess[row][j]==0)
{
int x=row,y=j;
while(x<chess.length)
{
chess[x][y] = 1;
x++;
}
x = row;
while(x<chess.length && y>=0)
{
chess[x][y] = 1;
x++;
y--;
}
x = row;
y = j;
while(x<chess.length && y<chess[0].length)
{
chess[x][y] = 1;
x++;
y++;
}
printNQueens(chess,qsf + row + "-" + j + ", ",row+1);
x = row;
y = j;
while(x<chess.length)
{
chess[x][y] = 0;
x++;
}
x = row;
while(x<chess.length && y>=0)
{
chess[x][y] = 0;
x++;
y--;
}
x = row;
y = j;
while(x<chess.length && y<chess[0].length)
{
chess[x][y] = 0;
x++;
y++;
}
}
}
}
}
【问题讨论】:
-
这是因为您可能在函数开头为
1的递归调用之后将国际象棋字段设置为0。最简单的解决方法是复制用于递归调用的数组并在其中设置额外的1s,同时保持原始数组不变。 -
@flyx 成功了。我正在使用无法正常工作的克隆功能。所以,我遍历并复制了每个元素。我想知道虽然使用这种方法会显着增加内存使用量和复杂性,对吧?
-
是的,内存使用会增加,复杂度可能(需要计算)。为了减少内存使用并能够正确回溯,而不是记住板子,标记每个占用的行、列和对角线。由于每个只能被占用一次,因此可以在递归调用后重置它们。然后计算一个字段是否空闲将进行三个比较而不是一个,这是一个常数,因此不会降低复杂性。
-
@flyx 我找到了一种使用数组列表的方法。请检查我发布的答案,让我知道它是否比每次都复制整个数组更好
标签: java recursion backtracking n-queens