八皇后问题介绍
八皇后问题,是一个古老而著名的问题,是回溯算法的典型案例.在8x8格的国际象棋上摆放8个皇后,使其不能互相攻击,即:任意两个皇后都不能处于同一行,同一列或同一斜线上,问有多少中摆法(92)
八皇后问题算法思路分析
- 第一个皇后先放第一行第一列
- 第二个皇后放在第二行第一列,然后判断是否OK,如果不OK,继续放在第二列,第三列,依次把所有列都放完,找到一个合适的
- 继续放第3个皇后,还是第一列,第二列.......知道第8个皇后也能放在一个不冲突的位置,算是找到了一个正确的解
- 当得到一个正确解时,在栈回退到上一个栈时,就会开始回溯,即将第一个皇后,放到第一列的所有正确解,全部得到.
- 然后回头继续第一个皇后放到第二列,后面继续循环执行1,2,3,4的步骤
- 示意图:
说明
- 理论上应该创建一个二维数组来表示棋盘,但是实际上可以通过一个算法,用一个一维数组即可解决问题.arr[8] = {1,4,7,5,2,6,1,3}
- 对应arr下标,表示第几行,即第几个皇后,arr[i] = val,val表示第i+1个皇后,放在第i+1行的val+1列.
代码实现
public class queue8 {
//定义一个max表示多少个皇后
int max = 8;
//定义一个数组,保存皇后放置位置的结果,比如arr={1,4,7,5,2,6,1,3}
int[] arr = new int[max];
static int count = 0;
public static void main(String[] args) {
queue8 que = new queue8();
que.check(0);
System.out.println("总共有:"+ count);
}
/**
* 放置第n+1个皇后
*
* @param n 皇后的下标
*/
public void check(int n) {
//结束递归的条件,n=8,表示0到7下标的皇后已经放置成功,即8个皇后都放置成功了
if (n == 8) {
print(); //打印放置结果
return;
}
for (int i = 0; i < max; i++) {
//把下标为n的皇后依次放在第1到8列的位置进行判断是否冲突
arr[n] = i;
if (judge(n)) { //不冲突
check(n+1); // 判断下一个
}
}
}
/**
* @param n 皇后的下标
* @return 不冲突返回true
*/
private boolean judge(int n) {
//判断冲突就是判断是否同列或者同斜线上
for (int i = 0; i < n; i++) {
//arr[i] == arr[n] 是否在同一行
//Math.abs(arr[n] - arr[i]) == Math.abs(n - i)是否在同同一斜线
if (arr[i] == arr[n] || Math.abs(arr[n] - arr[i]) == Math.abs(n - i)){
return false;
}
}
return true;
}
//打印放置的结果
private void print() {
count++;
for (int i : arr) {
System.out.print(i + " ");
}
System.out.println();
}
}