问题描述:

国际象棋的棋盘为8x8的方格棋盘。现将“马”放在任意指定的方格中,按照“马”走棋的规则将“马”进行移动。要求每个方格只能进入一次,最终使得“马”走遍棋盘的64个方格。

编写一个c程序,实现马踏棋盘操作,要求1~64这64个数字标注马移动的路径,也就是按照求出的行走路线,将数字1,2,3,......,64依次填入棋盘的方格中,并输出。

问题分析:

国际象棋中,“马”的移动规则如下图所示

  1   2  
8       3
    10    
7       4
  6   5  

途中10代码“马”的位置,它下一步可移动到图中其他八个位置上,该规则叫做“马走日”。但是如果“马”位于棋盘的边界附件,那么它下一步可移动到的位置就不一定有8个了,因为要保证“马”每一步都走在棋盘中

马踏棋盘的问题其实就是要将1,2,3,.......,64填入到一个8x8的矩阵中,要求相邻的两个数按照“马”的移动规则放置在矩阵中。

例如数字 a放置在矩阵(i,j)位置上,数字a+1只能放置在矩阵的(i-2,j+1),(i-1,j+2),(i+1,j+2),(i+2,j+1),(i+2,j-1),(i+1,j-2),(i-1,j-2),(i-2,j-1)之中的一个位置上。将矩阵填满并输出。

这样在矩阵中从1,2,......遍历到64,就得到了马踏棋盘的行走路径。因此本题的最终目的是输出一个8*8的矩阵,在该矩阵中填有1,2,......64这64个数字,相邻数字之间遵循“马走日”的规则。

算法设计:

解决马踏棋盘问题的一种比较容易理解的方法是应用递归的深度优先搜索的思想。因为“马”每走一步都是盲目的,它并不能判断当前的走步一定正确,而只能保证当前这步是可走的。

“马”走的每一步棋都是从它当前位置出发,向下一步的8个位置中的1个行走(在它下一步有8个位置可走的情况下)。因此“马”当前所走的路径并不一定正确,因为它可能还有剩下的可选路径没有尝试“马”的行走过程实际上就是一个深度探索的过程。“探索树”的跟节点为“马”在棋盘中的初始位置。

接下来“马”有两种行走方式,于是根节点派生出两个分支。而再往下一步行走,根节点的两个孩子又能够分别派生出其他不同的“行走路线”分支,如此派生下去,就得到了“马”的所有可能的走步状态。

可以想见,该探索树的叶子节点只可能有两种状态:一是该节点不能再派生出其他的“走步”分支了,也就是“马”走不通了;二是棋盘中的每个方格都被走到,即“马”踏遍棋盘。于是从该探索树的根节点到第二种情况的叶节点构成的路径,就是马踏棋盘的行走过程。

如何才能通过搜索这棵树探索树,找到这条马踏棋盘的行走路径呢?可以采用深度优先搜索的方法以先序的方式访问树中的各个节点,直到访问到叶节点。

如果叶节点是第二种情况的叶节点,则搜索过程可以结束,因为找到了马踏棋盘的行走路径;如果叶节点为第一种情况的叶节点,即走不通了,则需要返回到上一层的节点,顺着该节点的下一条分支继续进行深度优先搜索下去。

因此再设计“马踏棋盘”的算法时可以借鉴图的深度优先遍历算法和二叉树的先序遍历算法。但是在这里并不需要真正地构建这样一棵探索树,只需要借用探索树地思想。

在实际地操作过程中,所谓的探索树实际就是深度优先搜索地探索路径,每个节点实际就是当前地棋盘状态,而所谓地叶节点或者是在当前棋盘状态下,“马”无法再进行下一步行走;或者是马踏棋盘成功。

完整程序:

备注:因为程序涉及深度搜索,运行中叶节点不能再派生出其他的“走步”分支时,也就是“马”走不通了,则返回上一节点,比较复杂,运行较慢。(一般需要一分钟左右出现结果,请耐心等待。)

#include <stdio.h>

#define X 8

#define Y 8

int chess[X][Y];

int nextxy(int *t,int *y,int count)/**/

{

switch(count)

{

case 0;

if(*x+2<=X-1 && *y-1<=0 && chess[*x+2][*y-1] == 0)

{

*x = *x + 2;

*y = *y - 1;

return 1;

}

break;

case 1;

if(*x+2<=X-1 && *y+1<=Y-1 && chess[*x+2][*y+1] == 0)

{

*x = *x + 2;

*y = *y + 1;

return 1;

}

break;

case 2;

if(*x+1<=X-1 && *y-2>=0 && chess[*x+1][*y-2] == 0)

{

*x = *x + 1;

*y = *y - 2;

return 1;

}

break;

case 3;

if(*x+1<=X-1 && *y+2<=Y-1 && chess[*x+1][*y+2] == 0)

{

*x = *x + 1;

*y = *y + 2;

return 1;

}

break;

case 4;

if(*x-2>=0 && *y-1>=0 && chess[*x-2][*y-1] == 0)

{

*x = *x - 2;

*y = *y - 1;

return 1;

}

break;

case 5;

if(*x-2>=0 && *y+1<=Y-1 && chess[*x-2][*y+1] == 0)

{

*x = *x - 2;

*y = *y + 1;

return 1;

}

break;

case 6;

if(*x-1>=0 && *y-2>=0 && chess[*x-1][*y-2] == 0)

{

*x = *x - 1;

*y = *y - 2;

return 1;

}

break;

case 7;

if(*x-1>=0 && *y+2<=Y-1 && chess[*x-1][*y+2] == 0)

{

*x = *x - 1;

*y = *y + 2;

return 1;

}

break;

default;

break;

}

return 0;

}

int TravelChessBoard(int x,int y,int tag)/**/

{

int x1=x,y1=y,flag=0,count=0;

chess[x][y]=tag;

if(tag == X*Y)

{

return 1;

}

flag = netxy(&x1,&y1,count);

while(flag == 0 && count < 7)

{

count = count + 1;

flag = netxy(&x1,&y1,count);

}

while(flag)

{

if(TravelChessBoard(x1,y1,tag+1))

return 1;

x1 = x;

y1 = y;

count = count + 1;

flag = netxy(&x1,&y1,count);/**/

while(flag == 0 && count < 7)

{

count = count + 1;

flag = netxy(&x1,&y1,count);

}

}

if(flag == 0)

chess[x][y] = 0;

return 0;

}

int main()

{

int i,j;

for(i=0;i<X;i++)

for(j=0;j<Y;j++)

chess[i][j]=0;

if(TravelChessBoard(2,0,1))

{

for(i=0;i<Y;i++)

{

for(j=0;j<Y;j++)

printf("%-5d",chess[i][j]);

printf("\n");

}

printf("The horse has travel the chess board\n");

}

else

printf("The horse has travel the chess board\n");

return 0;

}

运行结果:

43 50 47 38 57 52 61 32

48 37 44 51 46 33 58 53

1 42 49 56 39 60 31 62

36 15 40 45 34 29 54 59

41 2 35 16 55 24 63 30

14 5 12 9 22 19 28 25

3 10 7 20 17 26 23 64

6 13 4 11 8 21 18 27

The horse has travel the chess board

此文章内容以及实例来源于《c语言学习app》,谢谢共享

马踏棋盘---c语言相关推荐

  1. 数据结构与算法|马踏棋盘算法(小甲鱼)C语言代码的算法分析

    马踏棋盘算法(骑士周游问题)的算法分析 C语言代码部分来自小甲鱼的<数据结构与算法> 文章目录 马踏棋盘算法(骑士周游问题)的算法分析 一.C语言代码实现 二.代码分析与算法思路 题目要求 ...

  2. c语言马踏棋盘编程分析,C语言马踏棋盘实现

    原标题:C语言马踏棋盘实现 问题描述 国际象棋的棋盘为8×8的方格棋盘.现将"马"放在任意指定的方格中,按照"马"走棋的规则将"马"进行移动 ...

  3. c语言数据结构之马踏棋盘

    c语言数据结构之马踏棋盘 马踏棋盘游戏 (一)思路: 马随机放在国际象棋的 8×8 棋盘 Board[07][07]的某个方格中,马按走棋规则进行移动.要求每个方格只进入一次,走遍棋盘上全部 64 个 ...

  4. c语言字符马图案,C语言实现马踏棋盘

    //马踏棋盘主要要考虑三个因素: //第一:马走的位置用Move数组表示,以及棋盘的大小不再是8*8,而是12*12: //第二:只要找到马可以踏的下一个位置,就进行递归,只有一只进行递归,这是一种理 ...

  5. 马踏棋盘问题的程序c语言,C语言马踏棋盘

    问题描述 国际象棋的棋盘为8×8的方格棋盘.现将"马"放在任意指定的方格中,按照"马"走棋的规则将"马"进行移动.要求每个方格只能进入一次, ...

  6. 数据结构——马踏棋盘题解(贪心算法)(C语言)

    数据结构--马踏棋盘题解(贪心算法) 使用循环建立棋盘与权值棋盘(权值为该位置可走的位置数量) 将当前步数写入棋盘数组中 开始探测下一步该走的位置, 分别测试八个方向 对可走位置进行查询权值,将权值最 ...

  7. 【大话数据结构C语言】43 图的应用 - 马踏棋盘算法

    欢迎关注我的公众号是[CodeAllen],关注回复[1024]获取资源 程序员技术交流①群:736386324 ,程序员技术交流②群:371394777 题目要求: 国际象棋的棋盘为8*8的方格棋盘 ...

  8. 【算法篇】/*一篇博客带你详细了解马踏棋盘问题*/(java语言实现)

    [前言]本文部分内容引用于b站尚硅谷老师的资料,如有侵权,请及时联系作者! hello大家好! 我依然是你们熟悉的槿凉.那么最近呢由于躺平了几天,也没有来得及更新博客,没有办法啦!学校封的严严实实,闷 ...

  9. 用贪心算法解决马踏棋盘问题

    用贪心算法解决马踏棋盘问题 参考文章: (1)用贪心算法解决马踏棋盘问题 (2)https://www.cnblogs.com/Allen-win/p/7095293.html 备忘一下.

最新文章

  1. 如何让phpmyadmin输入密码再进入
  2. 20165328 预备作业3 Linux安装及命令
  3. 使用python对比两个目录下的文件名差异
  4. Linux-Ubuntu Server 16.04安装JDK以及配置JDK环境变量
  5. CF 277.5 B.BerSU Ball 二分图的最大匹配 模版题
  6. android+4.4.2+横屏,Android 横竖屏和布局问题
  7. 第一次写博,好激动啊!
  8. VALSE学习(九):物体检测进展
  9. Windows下修改hosts文件
  10. SDCC和Keil之stc89c52资料(纪念51单片机40周年)
  11. Web认证如何对接第三方认证平台?
  12. 电子器件系列27:无源蜂鸣片
  13. 【Promise】自定义 - 手写Promise - Promise.all - Promise(executor)
  14. C语言实现扫雷小游戏(具体步骤+具体说明)
  15. 深度学习 噪声抑制_使用深度学习抑制噪声
  16. 让我们红尘作伴活得潇潇洒洒
  17. Linux 远程连接
  18. NFT跟元宇宙有什么关系?
  19. 求某数0次幂到n次幂之和
  20. elasticsearch:使用top_hits聚合获取分组列表

热门文章

  1. 《国富论》各译本之粗略比较
  2. iPhone 13首个正面照曝光:苹果真的改外形了!
  3. 微信html5上传图片闪退,web-view 里面的h5上传图片,部分苹果手机闪退,急!!!...
  4. 轨迹规划之 贝塞尔曲线
  5. 求二次、三次贝塞尔曲线的某个时间的位置及切线方向
  6. python换行和回车的区别_终于搞懂了回车与换行的区别
  7. vue 接入 facebook 登录的方法(需要翻墙),使用vue-facebook-signin-button插件
  8. 使用Java实现短信验证码
  9. mysql插入新字段方法
  10. java 非法参数异常_Java的比较抛出非法参数异常