问题描述:
n 皇后问题研究的是如何将 n 个皇后放置在 n×n 的棋盘上,并且使皇后彼此之间不能相互攻击,即任意两个皇后都不能处于同一行、同一列或同一斜线上。
思路:
一行一行地摆放,在确定一行中的那个皇后应该摆在哪一列时,需要当前列是否合法,如果合法,则将皇后放置在当前位置,并进行递归,回溯。每行都摆满皇后时,则产生了一种解法,将所有解法收集并返回。
判断合法:当前将要摆放’Q’的位置和其他已摆放‘Q’的位置不能在同一列,且不能在同一条45度斜线或135度斜线上。这里判断是否在同一条斜线上可通过当前将要摆放’Q’的位置和其他已摆放‘Q’的位置横坐标之差和纵坐标之差的绝对值是否相等来判断
代码:
public class nQueen {
int n;//皇后个数
int sum;//当前可行方案数
int[] brr;//当前解
public nQueen(int size) {
sum = 0;
n = size;
brr = new int[n + 1];
for (int i = 0; i < n; i++) {
brr[i] = 0;
}
}
//判断是否可以放在该地方
//不能出现列同行或者在一条斜线上(斜率不能相等)
boolean place(int k) {
for (int i = 1; i < k; i++) {
if (brr[k] == brr[i] || Math.abs(k - i) == Math.abs(brr[k] - brr[i])) return false;
}
return true;
}
public void Back(int k) {
//所有的皇后都遍历过了
if(k>n){
sum++;
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= n; j++) {
if(brr[i]!=j){
System.out.print("# ");
}
else {
System.out.print("Q ");
}
}
System.out.println();
}
System.out.println();
}
else {
for (int j = 1; j <= n; j++) {
//输出第k行符合条件的列
brr[k]=j;
if(place(k)){
Back(k+1);
}
}
}
}
public int getNum(){
Back(1);
return sum;
}
public static void main(String[] args) {
nQueen queen=new nQueen(4);
int sum=queen.getNum();
System.out.println(sum);
}
}
运行结果: