八皇后问题国际西洋棋棋手马克斯·贝瑟尔于1848年提出:在8×8格的国际象棋上摆放八个皇后,使其不能互相攻击,即任意两个皇后都不能处于同一行、同一列或同一斜线上,问有多少种摆法。
思路:试错,类似迷宫
试错过程:
1.第1行找到第一个合适的位置后直接进入第2行
2.第2行找到的位置跟已经放上去的元素做计算,判断是否复合要求(不能攻击),遍历直到找到第一个满足的元 素,直接 进入第三行
3.第3行如果所有的元素都不合适,则返回第二行,顺着原来的位置向后找,如果找到合适的元素,再次进入第三 行,如果 第2行没有合适的,则跳回第一行,第一行从上一个合适的元素向后寻找。。。。。。
互相攻击的两种可能性:
1.两个棋子处于同一列
2.两个棋子交叉处于一条45度斜线上;
事实上根据这些描述和接下来的代码,要看明白解题过程,依然会有一些困难,即便看明白了,理解不够深,过一段时间依然会忘记,最好的方式就是亲眼看到程序实现的过程,然后逆推程序的流程,真正搞明白解题思路,想要做到这一点,需要借助debugger工具, 代码后面会介绍如何借助debugger观察程序执行过程以及皇后位置的变动,特别是回退,前进的跳转;
代码如下:
//借助debugger能够非常清晰地看到跳转的过程!
var n = 8;
var arr = [];
var str = "";
function queen( index ) {
if( index === n ) {
str += arr;//每次完成一种情况,输出数组;
str += " "//空格隔离
}else{
for( var i = 0; i < n; ++i ) {
arr[ index ] = i;//为第一行的皇后寻找位置,从0开始,直到7
var flag = true;//这里主要是为判定可攻击性提供一个开关,如果在攻击范围内
// 则不进入下一列,继续向下寻找,如果找到了合适的位置,则进入下一行
for( var j = 0; j < index; ++j ) {
//这里是为了判定攻击范围,把所有已经放置的皇后与当前放置的皇后做位置计算,如果在攻击范围内,flag为false,不在所有已经放置的皇后的攻击范围内,则不改变flag的属性:true
if( arr[ index ] === arr[ j ]
|| arr[ index ] - arr[ j ] === j - index ) {
flag = false;
break;
};
};
if( flag ) {//这里是根据flag的属性判定是否进入下一行的循环;
queen( index + 1 );
}
}
}
};
queen( 0 );//从第0行进行试探
console.log( str )//输出拼接字符串所有情况
//queen(0)===》思路:是从第一行开始放棋子, 每放一个就检查是否处于被攻击的范围,处于被攻击范围则向后移动一个,如果所在位置并不会被攻击到则进入到下一行,
//代码中已经标注了debugger的位置;