回溯算法解决N皇后问题,并渲染为页面展示,代码可以直接复制在本地跑
注意:img图片要自行替换为你本地的图片
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Eight Queens Puzzle(Recursive algorithm) - 八皇后问题(递归算法)</title>
<style type="text/css">
body {
background-color: #ffffc0;
}
p {
text-align: center;
}
.container {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
}
.footer {
display: flex;
width: 100%;
flex-direction: column;
justify-content: start;
align-items: center;
}
table {
border-width: 8px;
border-color: #604040;
border-style: solid;
background-color: #ffffff;
}
td {
text-align: center;
vertical-align: middle;
width: 70px;
height: 70px;
}
tr:nth-child(2n+1) td:nth-child(2n) {
background-color: #000000;
}
tr:nth-child(2n) td:nth-child(2n+1) {
background-color: #000000;
}
img {
max-width: 100%;
max-height: 70px;
display: block;
margin: auto;
}
#seekbtn {
width: 350px;
height: 30px;
}
</style>
</head>
<body>
<p>
Eight Queens Puzzle (Recursive algorithm) - 八皇后问题(递归算法)<br />
2022.9.12</p>
<div class="container">
<table cellpadding="0" cellspacing="0" id='table'></table>
<div class="footer">
<p style="color: red;">使用说明:首先输入皇后数量,然后点击生成棋盘,然后不断点击生成解按钮,在棋盘中绘制皇后</p>
<div style="margin-bottom: 10px;">
<input type="text" id="input" placeholder="请输入皇后的个数" value="">
<input type="button" id='confim' value="点击生成棋盘">
</div>
<input type="button" id="seekbtn" value="点击开始搜索解..." />
</div>
</div>
</div>
</body>
<script>
const result = [];
function Nqueue(n) {
if (n < 1) return 0;
record = new Array(n);// record[i] 的值表示第i行,皇后所在的位置
return process(record, 0, n);
}
function process(record, i, n) {
if (i == n) {
result.push([...record])
return 1;
}
let res = 0;
for (let j = 0; j < n; j++) {
if (isValid(record, i, j)) {
record[i] = j;
res += process(record, i + 1, n);
}
}
return res;
}
function isValid(record, i, j) {
// 判断前i-1行每行中,皇后所在的位置,即在哪一列
for (k = 0; k < i; k++) {
if (j == record[k] || Math.abs(k - i) == Math.abs(record[k] - j)) {
return false;
}
}
return true;
}
let allCount = 0
let count = 1;
const btn = document.getElementById("seekbtn");
const confimObj = document.getElementById('confim')
const renderTable = (n) => {
btn.disabled = false;
count = 1;
btn.value = `点击开始搜索解...`;
let htmlStr = '';
const trArr = [];
for (let i = 0; i < n; i++) {
let tr = `<tr>`;
for (let j = 0; j < n; j++) {
tr += `<td id='r${i}c${j}'></td>`
}
tr += `</tr>`;
trArr.push(tr);
}
htmlStr += trArr.join('');
document.getElementById('table').innerHTML = htmlStr;
}
const renderQueue = () => {
// 将所有的td中的内容清空
const tds = document.getElementsByTagName("TD");
for (let i = 0; i < tds.length; i++) {
tds[i].innerHTML = "";
}
// 绘制新的图片
const curRes = result.length > 0 ? result.shift() : [];
for (let r = 0; r < curRes.length; r++) {
document.getElementById("r" + r + "c" + curRes[r]).innerHTML = `<img src="f0.png" />`;
}
if (allCount > 0) {
btn.value = ""
btn.value = `一共${allCount}组解,已经搜索到第${count}组解,点击搜索第${count + 1}组解...`;
if (count === allCount) {
btn.disabled = true;
} else {
count++;
}
} else {
btn.value = `输入的皇后数量无解,请重置皇后数量`
}
}
confimObj.addEventListener('click', () => {
const inputObj = document.getElementById('input');
renderTable(inputObj.value)
allCount = Nqueue(Number.parseInt(inputObj.value))
})
btn.addEventListener('click', renderQueue)
</script>
</html>
在线演示地址:http://bianyinglong.3vkj.net/Nqueue/
参考文档:https://blog.51cto.com/mengliao/536391