AcWing 843. n-皇后问题 ( JavaScript )
原题链接
中等
作者:
gaobowen
,
2019-11-30 11:06:58
,
所有人可见
,
阅读 877
1. 按每行只放一个皇后搜索
let n = 0;
let output = [];
//存放对已经放过皇后位置的标记
let row = [], col = [], diagonal = [], backDiagonal = [];
let init = n => {
row = new Int32Array(n);
col = new Int32Array(n);
diagonal = new Int32Array(2 * n);
backDiagonal = new Int32Array(2 * n);
for (let i = 0; i < n; i++) {
output[i] = new Array(n).fill('.');
}
}
//按每行只能放一个进行搜索
let dfs = x => {
if (x === n) { //每行都放完
for (let i = 0; i < n; i++) {
console.log(output[i].join(''));
}
console.log('');
return;
}
for (let y = 0; y < n; y++) {
// 检查每列和两对角线是否有冲突
// (正对角线:y=-x+b;反对角线:y=x+b 则有 r=2,i=1与r=1,i=2 在同一条正对角线,反对角-i+n)
if (col[y] || diagonal[x + y] || backDiagonal[x - y + n]) continue;
col[y] = diagonal[x + y] = backDiagonal[x - y + n] = 1;
output[x][y] = 'Q';
dfs(x + 1);//进入下一行
output[x][y] = '.';//回溯
col[y] = diagonal[x + y] = backDiagonal[x - y + n] = 0;
}
}
n = 4;
init(n);
dfs(0);
2. 按每个格子放皇后与不放皇后进行搜索
let n = 0;
let output = [];
//存放对已经放过皇后位置的标记
let row = [], col = [], diagonal = [], backDiagonal = [];
let init = n => {
row = new Int32Array(n);
col = new Int32Array(n);
diagonal = new Int32Array(2 * n);
backDiagonal = new Int32Array(2 * n);
for (let i = 0; i < n; i++) {
output[i] = new Array(n).fill('.');
}
}
//按每个格子放皇后与不放皇后进行搜索
let dfs2 = (x, y, s) => {
//从左到右,从上到下
if (y === n) y = 0, x++;
if (x === n) { //超出行数
if (s === n) { //已放完
for (let i = 0; i < n; i++) {
console.log(output[i].join(''));
}
console.log('');
}
return;
}
// 分支1,不放皇后
dfs2(x, y + 1, s);
// 分支2,放皇后
if (row[x] || col[y] || diagonal[x + y] || backDiagonal[x - y + n]) return;
row[x] = col[y] = diagonal[x + y] = backDiagonal[x - y + n] = 1;
output[x][y] = 'Q';
dfs2(x, y + 1, s + 1);//进入下一个位置
output[x][y] = '.';//回溯
row[x] = col[y] = diagonal[x + y] = backDiagonal[x - y + n] = 0;
}
n = 4;
init(n);
dfs2(0, 0, 0);