起因是最近在玩《雷顿教授与恶魔之箱》,遇到一个问题,用马走完国际象棋的棋盘(走日字,一个格子只能走一次),试了试,挺难的,尤其是棋盘大了以后,所以就想到了八皇后,感觉差不多,然后就想,嗯,不如写个程序来试试,结果发现已经不记得八皇后怎么写了,所以先看了下八皇后怎么写。
贴一下https://blog.csdn.net/gohike/article/details/53359691这篇里的实现
var n = 8;
var arr = [];
function queen(index) {
if (index === n) {
console.log(arr);
} else {
for (var i = 0; i < n; ++i) {
arr[index] = i;
var flag = true;
for (var j = 0; j < index; ++j) {
if (arr[index] === arr[j] || arr[index] - arr[j] === index - j || arr[index] - arr[j] === j - index) {
flag = false;
break;
};
};
if (flag) {
queen(index + 1);
}
}
}
}
queen(0);
我看了看,觉得稍微有一点点不太容易理解,所以改了改,把上面用arr的索引来作为行的方式改成了(x,y),回退的步骤也更明显了一点,结果发现我写的这种执行一下21ms,而上面这种2ms(捂脸)
var n = 8;
var arr = [];
function queen(index) {
if (index === n) {
console.log(arr.slice(0)); // 直接console.log(arr)的话可以发现无法展开看arr的值
} else {
for (var i = 0; i < n; ++i) {
arr.push({x:index,y:i}); // x表示行,y表示列
var flag = true;
for (var j = 0; j < index; ++j) {
if ((Math.abs(arr[index].x - arr[j].x) === Math.abs(arr[index].y - arr[j].y))
|| (arr[index].y === arr[j].y)) {
flag = false;
arr.pop(); // 回退一步
break;
};
};
if (flag) {
// 进入下一行
queen(index + 1);
}
}
}
// 两个循环都执行完了发现不行,那么回退一步,这步也会导致arr把所有可能穷尽一遍
arr.pop();
};
queen(0);
下面是马走棋盘的代码,6行5列执行结果有4542种走法,执行一下大概要花半分钟,惊了
var n = 6, m = 5;// n表示行,m表示列
var arr = [{x:1,y:1}];
var aaa = 0; // 计数用
function inRange(pos){
if(pos.x > n || pos.y > m || pos.x < 1 || pos.y < 1){ // 判断有没有跳出棋盘外
return false;
}
for(let i=0, len=arr.length; i<len; i++){ // 判断有没有走过
if(arr[i].x === pos.x && arr[i].y === pos.y){
return false;
}
}
return true;
}
function getPos(x,y,index){
switch(index){
case 1:
return {x:x+1,y:y+2}
break;
case 2:
return {x:x+1,y:y-2}
break;
case 3:
return {x:x+2,y:y+1}
break;
case 4:
return {x:x+2,y:y-1}
break;
case 5:
return {x:x-1,y:y+2}
break;
case 6:
return {x:x-1,y:y-2}
break;
case 7:
return {x:x-2,y:y+1}
break;
case 8:
return {x:x-2,y:y-1}
break;
}
}
function horse(index){
if(index === n*m){
aaa++;
}else{
for(let i=1; i<9; i++){
let temp = getPos(arr[index-1].x,arr[index-1].y,i);
if(inRange(temp)){
arr.push(temp);
horse(index+1);
}
}
}
// 8个位置走完发现没有可跳的
arr.pop();
}
horse(1);