
第一步:根据题目设定所需变量,我们需要一个int类型的N用于表示棋盘和皇后的数量,一个int类型的a[i]数组表示第i行的第j列存放着皇后,需要一个int类型的res记录结果。
第二步:经过分析发现,每一行只可能存在一个皇后,此时我们假设n个皇后均在每一行的第一个位置上,那么我们按照枚举的思想去移动最后一个皇后的每一个位置都会变成一种新的摆放方式,然后移动一下倒数第二行一次又会得到n个新的摆放方式,以此类推可以不落下任何一个摆放方法。但是聪明的你发现只要有两个皇后在同一列,那由它开始衍生的所有方法都不合法,所以我们可以在确定第i个皇后位置的时候就进行校验,只在与前一次相比合法的位置摆放就可以避免这个问题,最后记录结果,输出结果。
以下是代码解析:
import java.util.*;
// 1:无需package
// 2: 类名必须Main, 不可修改
public class Main {
static Scanner scan = new Scanner(System.in);
static int N = scan.nextInt();
static int[] a = new int [N];//a[i]=j表示第i行的第j个
static int res = 0;
public static void main(String[] args) {
Arrays.fill(a,-1);
dfs(0);
System.out.print(res);
}
public static void dfs(int row){//一行一行按列运行的,当row==N的时候说明已经运行到(最后一行+1)行了
if(row==N){
res++;
return;//每找到一种方法就记录一次
}
for(int j=0;j<N;j++){
if(check(row,j)){//如果该位置合法就继续遍历下一行
a[row] = j;
dfs(row+1);
a[row] = -1;//回溯
}
}
}
public static boolean check(int row,int col){
for(int i=0;i<row;i++){
if(a[i]==col){
return false;//同一列
}
if (i + a[i] == row + col){//争对(1,2)和(2,1)这类对角线
return false;
}
if (i - a[i] == row - col){//争对(1,1)和(2,2)这类对角线
return false;
}
}
return true;
}
}
1万+

被折叠的 条评论
为什么被折叠?



