61,110
社区成员
发帖
与我相关
我的任务
分享
<html>
<head>
<script>
var problem = [
[0,6,0,5,9,3,0,0,0],
[9,0,1,0,0,0,5,0,0],
[0,3,0,4,0,0,0,9,0],
[1,0,8,0,2,0,0,0,4],
[4,0,0,3,0,9,0,0,1],
[2,0,0,0,1,0,6,0,9],
[0,8,0,0,0,6,0,2,0],
[0,0,4,0,0,0,8,0,7],
[0,0,0,7,8,5,0,1,0]
];
var stack = [],flag = false;
function check20Grid(sudo,i,j){
let row = {}, col = {}, subSudo = {} //辅助变量
for(let k = 0; k < 9; k++){
let cur1 = sudo[i][k], cur2 = sudo[k][j];
if(cur1){ //当前元素已经在行中出现,优化掉零的判断,key为0时值为0,不需要额外判断
if(row[cur1])
return 1; //返回错误代码
else
row[cur1] = cur1; //当前元素未在行中出现,存入辅助变量中
}
if(cur2){ //列的判定与行类似,优化掉零的判断,key为0时值为0,不需要额外判断
if(col[cur2])
return 2;
else
col[cur2] = cur2;
}
//转化循环变量到小九宫格的坐标
let key = sudo[Math.floor(i/3)*3 + Math.floor(k/3)][Math.floor(j/3)*3+Math.floor(k%3)];
if(subSudo[key]) //九宫格判定与行类似,优化掉零的判断,key为0时值为0,不需要额外判断
return 3;
else
subSudo[key] = key;
}
return 0;
}
function findAnswer(){
for(let i = 0; i<9; i++){
for(let j = 0; j<9; ){
if(problem[i][j] === 0 || flag){ //当前位置为待定元素的首次处理或回溯到当前位置,两种情况看似不同,其实处理相同,自加1即可
flag = false;
let k = problem[i][j] + 1; //搜索向下一个合法值迈进
while(k<10){ //循环找到下一个合法值
problem[i][j] = k; //填值
if(check20Grid(problem,i,j) == 0){ //判定合法,相关二十格判定
stack.push([i,j++]); //存储回溯点,并步进
break;
}
k++;
}
if(k>9){ //当前位置找不到合法值,回溯
problem[i][j] = 0; //回溯前归零
let rt = stack.pop(); //堆栈中取回溯信息
if(!rt) //无解判断,返回0
return 0;
i=rt[0];
j=rt[1];
flag = true;
}
}
else{ //当前位置数字为题目给定
j++;
}
}
}
for(var n=0;n<9;n++) {
document.write(problem[n]+"<br>");
} //成功找到一组解
}
findAnswer();
</script>
</head>
<body>
<p> By Lunacia</p>
</body>
</html>
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
<html>
<head>
<script>
var problem = [
[0,6,0,5,9,3,0,0,0],
[9,0,1,0,0,0,5,0,0],
[0,3,0,4,0,0,0,9,0],
[1,0,8,0,2,0,0,0,4],
[4,0,0,3,0,9,0,0,1],
[2,0,0,0,1,0,6,0,9],
[0,8,0,0,0,6,0,2,0],
[0,0,4,0,0,0,8,0,7],
[0,0,0,7,8,5,0,1,0]
];
var stack = [],flag = false;
function check20Grid(sudo,i,j){
let row = {}, col = {}, subSudo = {} //辅助变量
for(let k = 0; k < 9; k++){
let cur1 = sudo[i][k], cur2 = sudo[k][j];
if(cur1){ //当前元素已经在行中出现,优化掉零的判断,key为0时值为0,不需要额外判断
if(row[cur1])
return 1; //返回错误代码
else
row[cur1] = cur1; //当前元素未在行中出现,存入辅助变量中
}
if(cur2){ //列的判定与行类似,优化掉零的判断,key为0时值为0,不需要额外判断
if(col[cur2])
return 2;
else
col[cur2] = cur2;
}
//转化循环变量到小九宫格的坐标
let key = sudo[Math.floor(i/3)*3 + Math.floor(k/3)][Math.floor(j/3)*3+Math.floor(k%3)];
if(subSudo[key]) //九宫格判定与行类似,优化掉零的判断,key为0时值为0,不需要额外判断
return 3;
else
subSudo[key] = key;
}
return 0;
}
function findAnswer(){
for(let i = 0; i<9; i++){
for(let j = 0; j<9; ){
if(problem[i][j] === 0 || flag){ //当前位置为待定元素的首次处理或回溯到当前位置,两种情况看似不同,其实处理相同,自加1即可
flag = false;
let k = problem[i][j] + 1; //搜索向下一个合法值迈进
while(k<10){ //循环找到下一个合法值
problem[i][j] = k; //填值
if(check20Grid(problem,i,j) == 0){ //判定合法,相关二十格判定
stack.push([i,j++]); //存储回溯点,并步进
break;
}
k++;
}
if(k>9){ //当前位置找不到合法值,回溯
problem[i][j] = 0; //回溯前归零
let rt = stack.pop(); //堆栈中取回溯信息
if(!rt) //无解判断,返回0
return 0;
i=rt[0];
j=rt[1];
flag = true;
}
}
else{ //当前位置数字为题目给定
j++;
}
}
}
outProblem();
}
function inputProblem() {
var ns = document.getElementById("tab").getElementsByTagName("input");
for (var i = 0; i < 9; i++)
for (var j = 0; j < 9; j++)
problem[i][j] = parseInt(ns[i*9+j].value, 10)||0;
}
function outProblem() {
var ns = document.getElementById("tab").getElementsByTagName("input");
for (var i = 0; i < 9; i++)
for (var j = 0; j < 9; j++)
ns[i*9+j].value = problem[i][j]||"";
}
window.onload = outProblem;
</script>
<style type="text/css">
#tab input {
width: 20px;
height: 20px;
text-align: center;
font-size: 18px;
}
</style>
</head>
<body>
<table id="tab">
<tr>
<td><input type="text" maxlength="1" /></td>
<td><input type="text" maxlength="1" /></td>
<td><input type="text" maxlength="1" /></td>
<td><input type="text" maxlength="1" /></td>
<td><input type="text" maxlength="1" /></td>
<td><input type="text" maxlength="1" /></td>
<td><input type="text" maxlength="1" /></td>
<td><input type="text" maxlength="1" /></td>
<td><input type="text" maxlength="1" /></td>
</tr>
<tr>
<td><input type="text" maxlength="1" /></td>
<td><input type="text" maxlength="1" /></td>
<td><input type="text" maxlength="1" /></td>
<td><input type="text" maxlength="1" /></td>
<td><input type="text" maxlength="1" /></td>
<td><input type="text" maxlength="1" /></td>
<td><input type="text" maxlength="1" /></td>
<td><input type="text" maxlength="1" /></td>
<td><input type="text" maxlength="1" /></td>
</tr>
<tr>
<td><input type="text" maxlength="1" /></td>
<td><input type="text" maxlength="1" /></td>
<td><input type="text" maxlength="1" /></td>
<td><input type="text" maxlength="1" /></td>
<td><input type="text" maxlength="1" /></td>
<td><input type="text" maxlength="1" /></td>
<td><input type="text" maxlength="1" /></td>
<td><input type="text" maxlength="1" /></td>
<td><input type="text" maxlength="1" /></td>
</tr>
<tr>
<td><input type="text" maxlength="1" /></td>
<td><input type="text" maxlength="1" /></td>
<td><input type="text" maxlength="1" /></td>
<td><input type="text" maxlength="1" /></td>
<td><input type="text" maxlength="1" /></td>
<td><input type="text" maxlength="1" /></td>
<td><input type="text" maxlength="1" /></td>
<td><input type="text" maxlength="1" /></td>
<td><input type="text" maxlength="1" /></td>
</tr>
<tr>
<td><input type="text" maxlength="1" /></td>
<td><input type="text" maxlength="1" /></td>
<td><input type="text" maxlength="1" /></td>
<td><input type="text" maxlength="1" /></td>
<td><input type="text" maxlength="1" /></td>
<td><input type="text" maxlength="1" /></td>
<td><input type="text" maxlength="1" /></td>
<td><input type="text" maxlength="1" /></td>
<td><input type="text" maxlength="1" /></td>
</tr>
<tr>
<td><input type="text" maxlength="1" /></td>
<td><input type="text" maxlength="1" /></td>
<td><input type="text" maxlength="1" /></td>
<td><input type="text" maxlength="1" /></td>
<td><input type="text" maxlength="1" /></td>
<td><input type="text" maxlength="1" /></td>
<td><input type="text" maxlength="1" /></td>
<td><input type="text" maxlength="1" /></td>
<td><input type="text" maxlength="1" /></td>
</tr>
<tr>
<td><input type="text" maxlength="1" /></td>
<td><input type="text" maxlength="1" /></td>
<td><input type="text" maxlength="1" /></td>
<td><input type="text" maxlength="1" /></td>
<td><input type="text" maxlength="1" /></td>
<td><input type="text" maxlength="1" /></td>
<td><input type="text" maxlength="1" /></td>
<td><input type="text" maxlength="1" /></td>
<td><input type="text" maxlength="1" /></td>
</tr>
<tr>
<td><input type="text" maxlength="1" /></td>
<td><input type="text" maxlength="1" /></td>
<td><input type="text" maxlength="1" /></td>
<td><input type="text" maxlength="1" /></td>
<td><input type="text" maxlength="1" /></td>
<td><input type="text" maxlength="1" /></td>
<td><input type="text" maxlength="1" /></td>
<td><input type="text" maxlength="1" /></td>
<td><input type="text" maxlength="1" /></td>
</tr>
<tr>
<td><input type="text" maxlength="1" /></td>
<td><input type="text" maxlength="1" /></td>
<td><input type="text" maxlength="1" /></td>
<td><input type="text" maxlength="1" /></td>
<td><input type="text" maxlength="1" /></td>
<td><input type="text" maxlength="1" /></td>
<td><input type="text" maxlength="1" /></td>
<td><input type="text" maxlength="1" /></td>
<td><input type="text" maxlength="1" /></td>
</tr>
</table>
<input type="button" value="start" onclick="inputProblem();findAnswer();" />
<p> By Lunacia</p>
</body>
</html>