八皇后问题:
要求:
要求皇后不能再同一行,不能在同一列,也不能在同一个斜线上面
思路:
1:先要构造八皇后的棋盘:表示皇后应该摆放的位置;这个可以用一位数组进行表示:下标表示的是放在棋盘的第几行,数组中的值表示放在棋盘中的第几列
2:思路:
(1):第一个皇后放在棋盘的第一行第一列
(2):第二个皇后放在第二行第一列,然后判断是否OK,如果不OK,继续放在第二行第二列,第三列,依次将所有列放完,直到找到一个合适的。
(3):继续第三个皇后,还是第一列,第二列直到八个皇后放在一个不冲突的位置上,算是找到了一个解
(4):当得到一个正确解之后,在栈回退到上一个栈的时候,就会开始回溯,即将第一个皇后,放在第一列的所有正确解,全部得到
(5):然后回头的时候第一个皇后放在第一行的第二列,后面继续1,2,3,4的步骤即可
代码如下所示:
public class EightProcess {
//定义一个max表示一共有多少个皇后
int max=8;
//定义一个数组arr保存皇后防止位置的保存结果,比如arr[8]={0,4,7,5,2,6,1,3}
int[]arr=new int[max];//因为棋盘是共享的所以写在外面
static int count=0;
static int judgeCount=0;
public static void main(String[] args) {
//测试:
EightProcess queue8=new EightProcess();
queue8.check(0);
System.out.println("一共有"+count+"解法");
System.out.println("一共判断了"+judgeCount+"次");
}
//编写一个方法放置第n个皇后
//注意:check每次递归的时候,进入该方法都会有for循环,执行完了才会退出,因此会有回溯
private void check(int n){
if(n==max){
//1:也就是说在n=8的时候,其实八个皇后已经放好了
print();
return;
}
//2:否则就是前面的8个皇后开始放置,判断是否冲突
for (int i = 0; i <max ; i++) {
//2.1:先把当前的皇后放在改行的第一列,判断是否冲突即可
arr[n]=i;
//2.2:并且判断是否发生冲突
if(judge(n)){//在这里默认结果是不冲突
//2.3:接着放n+1个皇后,即开始递归
check(n+1);//对于8个皇后,在同一层都会有8次循环
}
//一旦发生冲突,就继续执行arr[n]=i;也就是放入第二列,第三列等等
}
}
//当我们防止第n个的皇后的时候就去检测是否与前面已经摆放的皇后发生冲突
private boolean judge(int n){
judgeCount++;
/*说明:
* 1:arr[i]==arr[n]表示判断第n个皇后是否与前面的n-1个皇后在同一列:因为下标代表的数组里面的值
* 2:表示在同一列,同一斜线,Math.abs(int a)是一个算法,是绝对值
* 3:为什么没有说行数的关系,因为n就是代表的行数,是递增的,放了第一个,就会立马往第二行开始放*/
//n表示放置第n个皇后的时候
for (int i = 0; i <n ; i++) {
if(arr[i]==arr[n]||Math.abs(n-i)==Math.abs(arr[n]-arr[i])) {
return false;
}
}
return true;//表示当前的皇后与前面的皇后的位置是不会发生冲突的
}
//写一个方法,可以将皇后最后摆放的位置打印出来:也就是将那个数组打印出来即可
private void print(){
count++;
for (int i = 0; i <arr.length ; i++) {
System.out.print(arr[i]+" ");
}
System.out.println();
}
}
运行结果如下所示:、
分析:
递归回溯解决八皇后问题的方法很简单,但是效率低下。