运行时间:2115ms
占用内存:13580k
这个时间有点长,看别人都是<1ms的,不过总算是AC了/**
* n皇后问题
* 每一行每一列,同一斜线上不能出现2个皇后
* 解题思路:
* 回溯法
* 每列只能放1个皇后,每列就有n种方法,n列一共就是n^n种方法,这么多方法种可定包含了所有n皇后的解。当第一列放一个皇后的时候,就会产生一颗解空间树,由此树的第二层会有n个节点,第三层会有n*n个节点...
* 树的第n层会有n^n-1个节点,,这样就构成了一颗解空间树,这样的树随着第一列n种放皇后的情况,会有n棵树,那么一共就有n^n-1*n = n^n种解,那么如何在这些解中获取正确的答案?
* 随着一棵树开始,往下深度优先进行搜索,
* 1)当发现当前皇后的位置合法,继续往下搜索,知道叶子节点后,符合皇后解答,计数,然后回溯上一层,继续下一条分支
* 2)当发现当前位置不合法,那么就没有必要从当前节点往下衍生了,继续下一条分支
*/
package dp;
import java.util.Date;
import java.util.Scanner;
public class Main {
static int count = 0;
public static void main(String[] args){
Scanner in = new Scanner(System.in);
int n = in.nextInt();
nQueens(n);
System.out.println(count);
}
public static int nQueens(int n) {
if(n < 1) return 0;
// write code here
int[][] q = new int[n][n];
queens(0, q);//从第0列开始
return count;
}
public static void queens(int i, int[][] q){
if(i >= q.length){ //当前列递归出去了,结束
//递归结束,得到一组解
count++;
return ;
}
//根据当前列,应该有n中放法,从第一行开始到第n行进行讨论
for(int k = 0; k < q.length; k++){
if(isCorrect(k, i, q)){//当前k行,i列皇后合法,递归去处理下一列
q[k][i] = 1;//放上去
queens(i+1,q);//递归出列下一列,将所有合法的解记录夏下来(深度优先搜索)
q[k][i] = 0;//晴空当前位置,继续讨论下一颗解空间树,即当前列的下一行
}else{
//当前列当前行不合法,那么就去当前列的下一行
}
}
}
public static boolean isCorrect(int j, int k, int[][] q){
//判断当前位置的皇后是否合法
//该行
for(int i = 0; i < q.length; i++){
if(q[j][i] == 1 && i != k) return false;
}
//该列
for(int i = 0; i < q.length; i++){
if(q[i][k] == 1 && i != j) return false;
}
//左上
for(int i = j-1, w = k-1; i>=0 && w>=0; i--,w--){
if(q[i][w] == 1) return false;
}
//右下
for(int i = j+1, w = k+1; i<q.length && w < q.length; i++, w++){
if(q[i][w] == 1) return false;
}
//右上
for(int i = j-1, w = k+1; i>=0 && w<q.length; i--,w++){
if(q[i][w] == 1) return false;
}
//左下
for(int i = j+1, w = k-1; i < q.length && w >= 0; i++,w--)
if(q[i][w] == 1) return false;
return true;
}
}