八皇后回溯算法
由来
1848年,国际西洋棋棋手马克斯·贝瑟尔提出了这样的一个问题
在8×8格的国际象棋上摆放八个皇后,使其不能互相攻击,即任意两个皇后都不能处于同一行、同一列或同一斜线上,问一共有多少种摆法。
思路
先谈谈思路
1.将第一个皇后放在第一行第一列上
2.将第二个皇后放在第一行第一列上,发现与第一个处在同一列,不符合,遂将第二个皇后放在第二行第二列,发同一斜线,遂将其放在第二行第三列上。
3.将第三个皇后,还是第三行的第一列,第二列········到第8个列一个一个试,发现不冲突则将其放在应该的位置。
4.第四个,五个,六个,七个,八个,都是如此,直到八个位置都是正确解。
5.打个比方 当发现第六个皇后在第六行的每列都不符合要求,则开始回溯,回到第五列的那个位置,将皇后往后移一列,再检查是否符合规则,再开始后续其他皇后的放置。
图示:
代码:放置皇后
//放置第n个皇后
//check 是 每一次递归时,进入到check中都有 for(int i = 0; i < max; i++),因
//此会有回溯
private void check(int n) {
if(n == max) {
print();
return;
}
//依次放入皇后,并判断是否冲突
for(int i = 0; i < max; i++) {
//先把当前这个皇后 n , 放到该行的第1列
array[n] = i;
//判断当放置第n个皇后到i列时,是否冲突
if(judge(n)) { // 不冲突
//接着放n+1个皇后,即开始递归
check(n+1); //
}
//如果冲突,就继续执行 array[n] = i; 即将第n个皇后,放置在本行得 后移的一个位置
}
}
判断皇后是否冲突
private boolean judge(int n) {
judgeCount++;
for(int i = 0; i < n; i++) {
if(array[i] == array[n] || Math.abs(n-i) == Math.abs(array[n] - array[i]) ) {
return false;
}
}
return true;
}