马踏棋盘算法(骑士周游问题)的算法分析

C语言代码部分来自小甲鱼的《数据结构与算法》

文章目录

    • 马踏棋盘算法(骑士周游问题)的算法分析
  • 一、C语言代码实现
  • 二、代码分析与算法思路

题目要求

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

马踏棋盘的一个解:

对于在n*n的棋盘上,当n>=5且为偶数的时候,以任意点作点都有解。


回溯法:一条路走到黑,碰壁了再回来一条路走到黑…一般和递归可以很好的搭配使用,还有深度优先搜索(DFS)。

哈密尔顿路径:图G中的哈密尔顿路径指的是经过图G中每个顶点,且只经过一次的一条轨迹。如果这条轨迹是一条闭合的路径(从起点出发不重复地遍历所有点后仍能回到起始点),那么这条路径称为哈密尔顿回路。

一、C语言代码实现

#include<stdio.h>
#include<time.h>#define X 8
#define Y 8int chess[X][Y];
//找到基于(x,y)位置的下一个可走的位置
int nextxy(int *x,int *y,int count)
{switch(count){case 0:if(*x+2<=X-1&& *y-1>=0&&chess[*x+2][*y-1]==0){*x+=2;*y-=1;return 1;}break;case 1:if(*x+2<=X-1&& *y+1<=Y-1&&chess[*x+2][*y+1]==0){*x+=2;*y+=1;return 1;}break;case 2:if(*x+1<=X-1&& *y-2>=0&&chess[*x+1][*y-2]==0){*x+=1;*y-=2;return 1;}break;case 3:if(*x+1<=X-1&& *y+2<=Y-1&&chess[*x+1][*y+2]==0){*x+=1;*y+=2;return 1;}break;case 4:if(*x-1>=0&& *y-2>=0&&chess[*x-1][*y-2]==0){*x-=1;*y-=2;return 1;}break;case 5:if(*x-1>=0&& *y+2<=Y-1&&chess[*x-1][*y+2]==0){*x-=1;*y+=2;return 1;}break;case 6:if(*x-2>=0&& *y-1>=0&&chess[*x-2][*y-1]==0){*x-=2;*y-=1;return 1;}break;case 7:if(*x-2>=0&& *y+1<=Y-1&&chess[*x-2][*y+1]==0){*x-=2;*y+=1;return 1;}break;default:break;}return 0;
}void print()
{int i,j;for(i=0;i<X;i++){for(j=0;j<Y;j++){printf("%2d\t",chess[i][j]);}printf("\n");}printf("\n");
}//深度优先遍历棋盘
//(x,y)为位置坐标
//tag是标记变量,每走一步,tag+1
int TravelChessBoard(int x,int y,int tag)
{int x1=x, y1=y, flag=0 , count=0;chess[x][y] =tag;if( X*Y == tag ){//打印棋盘print();return 1;}//找到马的下一个可走的坐标(x1,y1),如果找到flag=1,否则为0flag = nextxy(&x1,&y1,count);while( 0 == flag && count < 7){count++;flag = nextxy(&x1,&y1,count);}while ( flag ){if( TravelChessBoard(x1,y1,tag+1) ){return 1;}//继续找到马的下一步可走的坐标(x1,y1),如果找到flag=1,否则为0x1=x;y1=y;count++;flag = nextxy(&x1,&y1,count);while( 0 == flag && count < 7){count++;flag = nextxy(&x1,&y1,count);}}if( 0 == flag){chess[x][y] = 0;}return 0;
}int main()
{int i, j;clock_t start,finish;start=clock();for( i=0; i < X; i++ ){for( j=0; j < Y; j++){chess[i][j] = 0;}}if(!TravelChessBoard(0,0,1)){printf("抱歉,马踏棋盘失败!\n");}finish=clock();printf("本次计算一共耗时:%f秒\n\n",(double)(finish-start)/CLOCKS_PER_SEC);return 0;
}

二、代码分析与算法思路

这里的起始位置是(0,0):如果起始位置是(2,0),可能需要很久的运行时间——因为由于一共有64次递归,每次递归最坏的情况可以有8次迭代,根据起始位置的不同,假设是最极端的情况时,可能需要8^(64)的时间复杂度。

算法思路

  1. 初始化二维数组

  2. 进入马踏棋盘算法TracelChessBoard(int x, int y,int tag)

    1. 初始化:x1=x,y1=y,flag=0,count=0

    2. 先假设该层马踏算法的位置行得通:chess[x][y]=tag

    3. 判断tag==X*Y:

      • 如果是:返回1。(已跑到最底层马踏算法:当tag==64时,算法成功,并完成了)
    4. 依次寻找马踏的下一个位置(count++)(第一次马踏):

      • 如果找到:改变x1和y1到马踏的下一个位置上,并返回1到flag;
      • 如果一直没找到(该位置无法进行下一步马踏):返回0到flag;
    5. 如果flag==1:

      • 如果下层马踏棋盘算法(基于第一次马踏后的位置)TracelChessBoard(x1,y1,tag+1)返回1,则此层马踏算法结束:返回1!(如果马踏的下一步也成功,返回1)

        1. 如果下层马踏棋盘算法TracelChessBoard(x1,y1,tag+1)一直返回1,(直到tag=X*Y时)则算法结束。
        2. 如果某一层马踏棋盘算法跳返回0,则(此时马踏的该位置的tag=0,flag=0)
      • (能进行到该步,意味着flag=0,该层位置行不通)初始化:x1=x,y1=y,该层count+=1(该位置(第一次马踏后的位置)都是死路,取消第一次马踏的位置,继续寻找该层马踏算法的下一个第一次马踏:count++);

      • 依次寻找马踏的下一个位置(count++):

        1. 如果找到:改变x1和y1到马踏的下一个位置上,并返回1到flag;

        2. 如果一直没找到(含有该层马踏算法的起始位置的路线都是死路):返回0到flag;

    6. 如果flag==0(即该层马踏算法都是死路):该层马踏算法的位置行不通,初始化该位置:chess[x][y]=0

    7. 返回0;

  3. 判断经过层层递归后的马踏棋盘算法:

    1. 如果算法最终返回0:算法失败!
    2. 如果算法最终返回1:打印二维数组,算法成功!

简述((Position>>>)position1>>>position2):

  1. 马儿来到这个岔路口positon1(如果有上一个岔路口,则假设为Position):

    1. 如果这个岔路口是终点,则胜利了。

    2. 马儿选择一条未走过、能走的路(从左往右选):

      1. 有得选,去到下个岔路口position2:

        1. 下个岔路口position2有路能走:记录岔路口position1,沿着该路到下个岔路口position2(令Position=position1,position1=position2),跳到(1);
        2. 下个岔路口(position2)无路能走:返回上一个岔路口(position1);

        以上两步可以不要,可以走到下个岔路口position2时,直接跳至(1)。

      2. 没得选,返回上一个岔路口(令position1=Position),跳至(1)。

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

  1. 数据结构(七)——Dijkasta 、Flyod、马踏棋盘算法

    Dijkstra 算法 应用场景-最短路径问题 有 7 个村庄(A, B, C, D, E, F, G) ,现在有六个邮差,从 G 点出发,需要分别把邮件分别送到A, B, C , D, E, F 六 ...

  2. Day600601.马踏棋盘算法 -数据结构和算法Java

    马踏棋盘算法 图的深度优先DFS 回溯 八皇后问题.小老鼠找迷宫问题 一.介绍 二.思路分析 三.代码实现 package com.achang.algorithm;import java.awt.* ...

  3. java 马踏棋盘优化_我所知道的十大常用算法之马踏棋盘算法(深度搜索、贪心思想优化 )...

    前言需求 今天我们学习的是马踏棋盘算法,我们还是从一个场景里引入看看 马踏棋盘算法也被称为骑士周游问题 将马随机放在国际象棋的6×6棋盘Board0-5的某个方格中 提示:马按走棋规则(马走日字)进行 ...

  4. 【算法】马踏棋盘算法 骑士走周游算法

    文章目录 1.概述 2.贪心优化 1.概述 马踏棋盘算法和八皇后问题很相似:[算法]八皇后问题 骑士周游问题的解决步骤和思路 创建棋盘chessBoard,是一个二维数组 将当前位置设置为已经访问,然 ...

  5. 用java写的马踏棋盘算法

    用java写的马踏棋盘算法 将马随机放在国际象棋的8×8棋盘Board[0-7][0-7]的某个方格中,马按走棋规则进行移动.要求每个方格只进入一次,走遍棋盘上全部64个方格. 代码 /* 马踏棋盘问 ...

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

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

  7. 马踏棋盘算法(骑士周游问题)

    要求: 国家棋盘为8*8的方格棋盘,将"马"放在任意指定方格中.最终让马走遍64个方格. 关于象棋中马的走法 如下图所示: 下面是代码: #include <stdio.h& ...

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

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

  9. 马踏棋盘---c语言

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

最新文章

  1. php数组如何写入txt文件中_php将数组写入到文件的三种方法
  2. Jquery中bind和live的区别
  3. IOS中的枚举的写法...
  4. 调用系统相机和相册,并且裁剪成圆形图片(解决6.0,7.0,8.0版本问题)
  5. 连续七天熬夜3D建模师终于出手,让老板增加薪资待遇,分享使用3D建模软件的6个行业
  6. elasticjob 分片策略
  7. 红米K20 Pro拍照样张出炉:后置4800万像素高清三摄
  8. python进阶05并发之一基本概念
  9. 一个简单的PopupWindow做的选项菜单点击按钮会在按钮下弹出几个下拉控件
  10. spark 连接mysql读取数据
  11. Docker 容器十诫
  12. [WEB]超牛的前端页面模板收集
  13. Qt更改字体为思源黑体
  14. Node版本管理工具 - Nvm的下载、安装配置与使用
  15. 从零开始写第一个Android应用程序
  16. 解决win10 自动同步时间灰色
  17. 计算机组成原理课程设计_微程序控制的运算器设计
  18. 把Excel转换成xml文件
  19. 沈阳大雨部分地区积水情况
  20. scrapy-splash安装使用

热门文章

  1. 六边形战士—雷达图实现
  2. 梦幻成仙,诛灭外挂——《梦幻诛仙手游》的阻击外挂之旅
  3. 异或差分序列_差分序列的性质及应用
  4. c语言程序设计论文背单词系统,C语言课程设计-背单词系统(含程序)
  5. IDEA使用问题 —— Inspection info 波浪线
  6. fourier feature networks
  7. 一个忙碌架构师的Java后端书架(2022)
  8. echarts中配置图例形状、图标宽高、图标和文字间距、图例位置、文字颜色、字体大小等基础配置
  9. mysql查附近500米商户_mysql查询附近门店
  10. googiehost免费空间申请