前一段时间写了篇n皇后的博客,近期有正在准备蓝桥杯,虽然已凉~~,但还是要挣扎一下嘛,所以再来优化一下上一篇博客的代码,顺便对递归和回溯有更充分的理解,接下来我们上代码,每条语句的意思都在注释里面了。
参考视频: https://www.bilibili.com/video/BV1bK4y1n7iq?from=search&seid=17252516836113335016
package cn.shi;
import java.util.Scanner;
/**
* n皇后 深搜+回溯
* @author Shi Jun Yi
*
*/
public class Main {
static int count = 0;//存放一共有多少种排法
static int n; //n个皇后
static int[] a = new int[10];//先表示10行,a[i] 表示第i行的皇后位于i上面
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
n = input.nextInt();//输入n的大小 但是不能超过10
dfs(1);//从第一行开始
System.out.println(count);
}
//递归,深搜,回溯
public static void dfs(int row) {//row表示第几行
if(row == n+1) {//说明到了边界,这就是一个解,
count++;
return ;
}
//如果没有到达边界那说明会有n种列的情况
for(int i=1;i<=n;i++) {
if(check(row,i)) {//check判断是否是同列或者是同一个对角线上的数
a[row] = i; //表示第row行的皇后位于i这个位置
dfs(row+1);//递归继续搜索下一行
a[row] = 0;//回溯,因为有很多解,所以我们递归之后必须回溯,
}
}
}
//检验函数 用来检验放在某个位置上的皇后是否合法,也就是说,放在某个位置上的皇后与此位置同行,同列,同对角线上有无其他皇后
public static boolean check(int x,int y) {
//循环从1到x 也就是说我们只需要从第一行到第x行的行数就可以了
for(int i=1;i<=x;i++) {//这里有一个疑点,i可不可以不等于x 我实验的结果是不等于x的值一样对,如果小伙伴们看到这一点还请告知我的观点是否正确
if(a[i] == y) {//判断是否同列 同行肯定是不会发生的 a[i]表示的是列,即这一行的皇后所处的位置是那一列
return false;
}
if(x+y == i+a[i]) {//判断主对角线 主对角线上有一个特点就是他们的横纵坐标相加的值相等
return false;
}
if(x-y == i-a[i]) {//判断副对角线 副对角线上有一个特点就是他们的横纵坐标相减的值相等
return false;
}
}
return true;
}
}
结果:
OK,二探n皇后就到这里啦,感谢小伙伴们支持~~
每日一励志:只要学不死,就往死里学