1技术路线: ① 界面设计:用户自主定义棋盘大小、用户定义起跳点;点击“确定”后 运行函数;打印结果 ② 点击“确定”后,运行函数“main()”,完成初始化工作;并进入查找路径的递归函数“Jump()”; ③ Jump()函数中,通过循环依次寻找八个方向,并判断所找点是否已经“走过”或者跳出棋盘,若无,则进入递归;判断到达出发点,打印输出 ④ 查找到一条路径后,回溯上一个点,继续运行当前“Jump()”,直至找完所有路径; 3.结果展示: ①界面 ②测试4*3棋盘,起始点(1,1)
【算法描述】
本题有较多方法求解,在此仅对回溯法进行分析。 一只马在棋盘的某一点,它可以朝8个方向前进,方向向量分别是:(2,1)、(2,-1)、(1,2)、(1,-2)、(-2,1)、(-2,-1)、(-1,2)、(-1,-2)。从中任选择一个方向前进,到达新的位置。在从新的位置选择一个方向前进,继续,直到无法前进为止。无法前进可能有如下原因:下一位置超出边界、下一位置已经被访问过。当马已经无法前进时,就回退到上一位置,从新选择一个新的方向前进;如果还是无法前进,就再回退到上一位置……
<DOCTYPRE html>
<html>
<head>
<title>
跳马
</title>
</head>
<body>
<!输入框设计>
<form action="/test.php" method="get">
跳马
<br><br><br>
棋盘坐标系:行为y轴,列为x轴<br>
棋盘行列说明:如3*4指 3行格子*4列格子,若理解为线条为4行线条*5列线条<br>
输入数据说明:为了您使用体验,请勿输入过大数据,这里我们的限制为10*10
<br>
<hr>
棋盘设计:
<br>
棋盘行数:<input type="number" name="row" id="row" min="0" max="10" />
棋盘列数:<input type="number" name="column" id="column" min="0" max="10"/>
<hr>
原始起跳点:
<br>
起跳点所在行:<input type="number" name="fromRow" id="fromRow" min="0" max="10" />
起跳点所在列:<input type="number" name="fromColumn" id="fromColumn" min="0" max="10"/>
<br>
<input type="submit" value="确定" οnclick="main()"/>
</form>
<script>
var direction=8; //跳跃方向
var MAX_STEP=50; //最大步数
var num=0;
var path=new Array(MAX_STEP + 1);
for(var i=0;i<(MAX_STEP+1);i++){
path[i]=new Array(2);
}//存路径
var dx=new Array( 0, 1, 2, 2, 1, -1, -2, -2, -1);//表示方向
var dy=new Array( 0, 2, 1, -1, -2, 2, 1, -1, -2);//表示方向
function Path(MAX_X, MAX_Y, step,xy){
for (var i = 0; i < MAX_Y;i++)
for (var j = 0; j < MAX_X; j++)
xy[i][j] = 0;
for (var i = 1; i < step; i++){
xy[path[i][1]][path[i][0]] = 1;
}
}
function Judgment(x, y, xy){
var judge = false;
if (xy[y][x]!=0)//重复结点,错误路径
judge = true;
else
xy[y][x] = 1;
return judge;//false为可行路径
}
function Jump( MAX_X, MAX_Y,x,y,step,xy){
var t1, t2, t3, t4;
var x1, y1;
Path(MAX_X, MAX_Y,step,xy);
for (var k = 1; k <= direction; k++){
//朝八个方向中的某个方向跳跃
x1 = x + dx[k];
y1 = y + dy[k];
//跳出边界,进入下一种路径的查找
if (x1 > MAX_X || y1 > MAX_Y || x1 < 0 || y1 < 0)
continue;
t1 = (x1 >= 0) && (x1 <= MAX_X);//左右边界内
t2 = (y1 >= 0) && (y1 <= MAX_Y);//上下边界内
//边界
t3 = (x1 == path[0][0]);
t4 = (y1 == path[0][1]);
if (t1 && t2){//在棋盘内
//记录位置
if (!Judgment(x1, y1,xy)){//返回false表示没有重复,可以继续寻找路径
//continue;
path[step][0] = x1;
path[step][1] = y1;
if (t3 && t4){
num++;
document.write("方案"+num+":");
for (var i = 0; i <= step; i++){
document.write( "("+path[i][0]+","+path[i][1]+")");
if (i != step)
document.write(" -> ");
}//for(i)
document.write("<br>");
}//if(t3456)
else{
Jump(MAX_X, MAX_Y,x1, y1, step + 1,xy);
}//else
}//if (!Judgment(x1, y1))
}//if(t1 && t2)
}//for(k)
}
function main(){
//初始位置
var MAX_X; //X轴最大边界
var MAX_Y; //Y轴最大边界
var a,b;
MAX_X=document.getElementById("column").value;
MAX_Y=document.getElementById("row").value;
a=path[0][0]=document.getElementById("fromColumn").value;
b=path[0][1]=document.getElementById("fromRow").value;
if(MAX_X>10 || MAX_Y>10 || a>10 ||b>10 || (a+1)>MAX_X || (b+1)>MAX_Y){
document.write("拒绝服务!请按照规范输入数据");
}
var xy=new Array(MAX_Y+1);
for(var i=0;i<MAX_Y+1;i++){
xy[i]=new Array(MAX_X+1);
}
for(var i=0;i<MAX_Y+1;i++){
for(var j=0;j<MAX_X+1;j++){
xy[i][j]=0;
}
}
Jump(MAX_X, MAX_Y,0, 0, 1,xy);
document.write("总方案数"+ num);
if(num==0){
document.write("没有唉!!!");
}
}
</script>
</body>
</html>
</DOCTYPRE>
|