数据结构与算法|马踏棋盘算法(小甲鱼)C语言代码的算法分析
马踏棋盘算法(骑士周游问题)的算法分析
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)的时间复杂度。
算法思路:
初始化二维数组
进入马踏棋盘算法
TracelChessBoard(int x, int y,int tag)
:初始化:
x1=x,y1=y,flag=0,count=0
;先假设该层马踏算法的位置行得通:
chess[x][y]=tag
;判断tag==X*Y:
- 如果是:返回1。(已跑到最底层马踏算法:当tag==64时,算法成功,并完成了)
依次寻找马踏的下一个位置(count++)(第一次马踏):
- 如果找到:改变x1和y1到马踏的下一个位置上,并返回1到flag;
- 如果一直没找到(该位置无法进行下一步马踏):返回0到flag;
如果flag==1:
如果下层马踏棋盘算法(基于第一次马踏后的位置)
TracelChessBoard(x1,y1,tag+1)
返回1,则此层马踏算法结束:返回1!(如果马踏的下一步也成功,返回1)- 如果下层马踏棋盘算法
TracelChessBoard(x1,y1,tag+1)
一直返回1,(直到tag=X*Y时)则算法结束。 - 如果某一层马踏棋盘算法跳返回0,则(此时马踏的该位置的tag=0,flag=0)
- 如果下层马踏棋盘算法
(能进行到该步,意味着flag=0,该层位置行不通)初始化:x1=x,y1=y,该层count+=1(该位置(第一次马踏后的位置)都是死路,取消第一次马踏的位置,继续寻找该层马踏算法的下一个第一次马踏:count++);
依次寻找马踏的下一个位置(count++):
如果找到:改变x1和y1到马踏的下一个位置上,并返回1到flag;
如果一直没找到(含有该层马踏算法的起始位置的路线都是死路):返回0到flag;
如果flag==0(即该层马踏算法都是死路):该层马踏算法的位置行不通,初始化该位置:
chess[x][y]=0
;返回0;。
判断经过层层递归后的马踏棋盘算法:
- 如果算法最终返回0:算法失败!
- 如果算法最终返回1:打印二维数组,算法成功!
简述((Position>>>)position1>>>position2):
马儿来到这个岔路口positon1(如果有上一个岔路口,则假设为Position):
如果这个岔路口是终点,则胜利了。
马儿选择一条未走过、能走的路(从左往右选):
有得选,去到下个岔路口position2:
- 下个岔路口position2有路能走:记录岔路口position1,沿着该路到下个岔路口position2(令Position=position1,position1=position2),跳到(1);
- 下个岔路口(position2)无路能走:返回上一个岔路口(position1);
以上两步可以不要,可以走到下个岔路口position2时,直接跳至(1)。
没得选,返回上一个岔路口(令position1=Position),跳至(1)。
数据结构与算法|马踏棋盘算法(小甲鱼)C语言代码的算法分析相关推荐
- 数据结构(七)——Dijkasta 、Flyod、马踏棋盘算法
Dijkstra 算法 应用场景-最短路径问题 有 7 个村庄(A, B, C, D, E, F, G) ,现在有六个邮差,从 G 点出发,需要分别把邮件分别送到A, B, C , D, E, F 六 ...
- Day600601.马踏棋盘算法 -数据结构和算法Java
马踏棋盘算法 图的深度优先DFS 回溯 八皇后问题.小老鼠找迷宫问题 一.介绍 二.思路分析 三.代码实现 package com.achang.algorithm;import java.awt.* ...
- java 马踏棋盘优化_我所知道的十大常用算法之马踏棋盘算法(深度搜索、贪心思想优化 )...
前言需求 今天我们学习的是马踏棋盘算法,我们还是从一个场景里引入看看 马踏棋盘算法也被称为骑士周游问题 将马随机放在国际象棋的6×6棋盘Board0-5的某个方格中 提示:马按走棋规则(马走日字)进行 ...
- 【算法】马踏棋盘算法 骑士走周游算法
文章目录 1.概述 2.贪心优化 1.概述 马踏棋盘算法和八皇后问题很相似:[算法]八皇后问题 骑士周游问题的解决步骤和思路 创建棋盘chessBoard,是一个二维数组 将当前位置设置为已经访问,然 ...
- 用java写的马踏棋盘算法
用java写的马踏棋盘算法 将马随机放在国际象棋的8×8棋盘Board[0-7][0-7]的某个方格中,马按走棋规则进行移动.要求每个方格只进入一次,走遍棋盘上全部64个方格. 代码 /* 马踏棋盘问 ...
- 【大话数据结构C语言】43 图的应用 - 马踏棋盘算法
欢迎关注我的公众号是[CodeAllen],关注回复[1024]获取资源 程序员技术交流①群:736386324 ,程序员技术交流②群:371394777 题目要求: 国际象棋的棋盘为8*8的方格棋盘 ...
- 马踏棋盘算法(骑士周游问题)
要求: 国家棋盘为8*8的方格棋盘,将"马"放在任意指定方格中.最终让马走遍64个方格. 关于象棋中马的走法 如下图所示: 下面是代码: #include <stdio.h& ...
- 马踏棋盘问题的程序c语言,C语言马踏棋盘
问题描述 国际象棋的棋盘为8×8的方格棋盘.现将"马"放在任意指定的方格中,按照"马"走棋的规则将"马"进行移动.要求每个方格只能进入一次, ...
- 马踏棋盘---c语言
问题描述: 国际象棋的棋盘为8x8的方格棋盘.现将"马"放在任意指定的方格中,按照"马"走棋的规则将"马"进行移动.要求每个方格只能进入一次 ...
最新文章
- php数组如何写入txt文件中_php将数组写入到文件的三种方法
- Jquery中bind和live的区别
- IOS中的枚举的写法...
- 调用系统相机和相册,并且裁剪成圆形图片(解决6.0,7.0,8.0版本问题)
- 连续七天熬夜3D建模师终于出手,让老板增加薪资待遇,分享使用3D建模软件的6个行业
- elasticjob 分片策略
- 红米K20 Pro拍照样张出炉:后置4800万像素高清三摄
- python进阶05并发之一基本概念
- 一个简单的PopupWindow做的选项菜单点击按钮会在按钮下弹出几个下拉控件
- spark 连接mysql读取数据
- Docker 容器十诫
- [WEB]超牛的前端页面模板收集
- Qt更改字体为思源黑体
- Node版本管理工具 - Nvm的下载、安装配置与使用
- 从零开始写第一个Android应用程序
- 解决win10 自动同步时间灰色
- 计算机组成原理课程设计_微程序控制的运算器设计
- 把Excel转换成xml文件
- 沈阳大雨部分地区积水情况
- scrapy-splash安装使用