N皇后问题是一个经典的回溯问题,我们回溯法的思想来对问题进行分析。
初步分析:由于N个皇后不同行,我们可以断定如果有解,则该解中N个皇后必定是每行一个,按照行顺序进行搜索,可以构建出解空间树。
-解空间树:按行顺序进行搜索,第i个皇后的位置就是第i行中的某一个,这样解空间就是一个n层的树。
-拓展规则:题目并没有要求输出结果的顺序,简单的按1…n的顺序进行拓展就可以了
-剪枝策略:我们的搜索策略已经能够保证不同行了,加一个列占用标志来确保不同列,通过判断来两个皇后的横纵坐标距离是否相等可以判断是否在45度斜线上。
:java代码
import java.util.Arrays;
import java.util.Scanner;
public class problem2553 {
static boolean []column_flag;
static int []position;
static int count;
static int []sum=new int[11];
public static void main(String[] args) {
// TODO Auto-generated method stub
Scanner scan=new Scanner(System.in);
int N;
column_flag=new boolean[10];
position=new int[10];
Arrays.fill(column_flag, true);
Arrays.fill(position, -1);
count=0;
pow();
while(true){
N=scan.nextInt();
if(N==0) break;
System.out.println(sum[N]);
}
}
//打表,不打表就会TLE
static void pow(){
for(int i=1;i<=10;i++){
count=0;
DFS_Search(-1,i);
sum[i]=count;
}
}
//current_row表示当前已经搜索完成的最后一行
static void DFS_Search(int current_row,int n){
if(current_row==n-1){
count++;
}
else{
for(int i=0;i<n;i++){
if(column_flag[i]){
boolean flag=true;
//45度检查
for(int j=0;j<=current_row;j++){
if(Math.abs(current_row+1-j)==Math.abs(i-position[j])){
flag=false;
break;
}
}
if(flag){
position[current_row+1]=i;
column_flag[i]=false;
DFS_Search(current_row+1,n);
column_flag[i]=true;
position[current_row+1]=-1;
}
}
}
}
}
}