马踏棋盘算法

「已注销」 2019-10-29 06:48:52
问题描述:国际象棋有8*8个格子,马只能走2*3的对角线,求马在任意起始位置不重复地走遍所有格子的方案

写了个没什么技术含量的,简称真 * 硬刚之术,以求抛砖引玉
ps:没有试,要算得算老半天,可能有许差错,另外虽然是C++写的,但一点C++的特性都没用,只是传递一下思想

深度优先+递归



#include<iostream>
using namespace std;
//传数组写快点,就不传指针了
void solve(int map[8][8], int coordL,int coordR) {
//已走的格子数
static int flag = 0;
//步数
int step = 0;
//马步方向
int direction[8][2] = { {1,2},{1,-2},{-1,2},{-1,-2},{2,1},{2,-1},{-2,1},{-2,-1} };
//方向控制
int control = 0;
//未走完时
if (flag < 64) {
//确保每次递归如果能走必须走一步
while (true) {
//如果下一步可走,则走
if (map[coordL + direction[control][0]][coordR + direction[control][1]] != 1
&& coordL < 8 && coordL >= 0 && coordR < 8 && coordR >= 0) {
coordL += direction[control][0];
coordR += direction[control][1];
//标记已经走过
map[coordL][coordR] = 1;
flag++;
step = flag;
}
//如果下一步不可走,则切换方向
else {
if (control < 8) {
control++;
}
else {
break;
}
}
}
//继续走下一步,并且在下一步无法进行时回退继续尝试其他走法
while (true) {
//进入下一步
solve(map, coordL, coordR);
//若下一步失败,则回退
if (flag < 64) {
map[coordL][coordR] = 0;
flag--;
coordL -= direction[control][0];
coordR -= direction[control][1];
//control为7时已无其他走法,不必再试
if (control < 7) {
control++;
}
else {
break;
}
//继续尝试其他走法
while (true) {
if (map[coordL + direction[control][0]][coordR + direction[control][1]] != 1
&& coordL < 8 && coordL >= 0 && coordR < 8 && coordR >= 0) {
coordL += direction[control][0];
coordR += direction[control][1];
map[coordL][coordR] = 1;
flag++;
step = flag;
}
else {
if (control < 8) {
control++;
}
else {
break;
}
}
}
}
else {
break;
}
}
}
//走完时
else {
cout << "第" << step << "步的走法为" << "[" << direction[control][0] << "," << direction[control][1] << "]" << endl;
}
}
int main() {
//初始化棋盘
int map[8][8];
for (int i = 0; i < 8; i++) {
for (int j = 0; j < 8; j++) {
map[i][j] = 0;
}
}
//初始化坐标,行列,就不设置检测了
int coordL, coordR;
scanf_s("%d %d", &coordL, &coordR);
//走起
solve(map,coordL,coordR);
return 0;
}
...全文
182 9 打赏 收藏 转发到动态 举报
写回复
用AI写文章
9 条回复
切换为时间正序
请发表友善的回复…
发表回复
「已注销」 2019-10-29
  • 打赏
  • 举报
回复
引用 7 楼 wowpH 的回复:
额,你直接告诉我输入多少吧。我试了好几个都不行。
不好意思,重新改了下,但是还有一个运行了小于1ms就栈溢出的毛病~~调试的时候是可以的,不知道你的vs是否可以运行

#include<iostream>
using namespace std;
//棋盘
int map[8][8];
//马步方向
int direction[8][2] = { {1,2},{1,-2},{-1,2},{-1,-2},{2,1},{2,-1},{-2,1},{-2,-1} };
//坐标,行列
int coordL, coordR;
//已走的格子数
int flag = 0;

void solve() {
	//步数
	int step = 0;
	//方向控制
	int control = 0;
	//下一步的坐标
	int fcoordL;
	int fcoordR;
	//未走完时
	if (flag < 64) {
		//确保每次递归如果能走必须走一步
		while (true) {
			fcoordL = coordL + direction[control][0];
			fcoordR = coordR + direction[control][1];
			//如果下一步可走,则走
			if (fcoordL < 8 && fcoordL >= 0 && fcoordR < 8 && fcoordR >= 0&& map[fcoordL][fcoordR] != 1) {
					coordL += direction[control][0];
					coordR += direction[control][1];
					//标记已经走过
					map[coordL][coordR] = 1;
					flag++;
					step = flag;
					break;
			}
			//如果下一步不可走,则切换方向
			else {
				if (control < 8) {
					control++;
				}
				else {
					break;
				}
			}
		}
		//继续走下一步,并且在下一步无法进行时回退继续尝试其他走法
		while (true) {
			//进入下一步
			solve();
			//若下一步失败,则回退
			if (flag < 64) {
				map[coordL][coordR] = 0;
				flag--;
				coordL -= direction[control][0];
				coordR -= direction[control][1];
				//control为7时已无其他走法,不必再试
				if (control < 7) {
					control++;
				}
				else {
					break;
				}
				//继续尝试其他走法
				while (true) {
					fcoordL = coordL + direction[control][0];
					fcoordR = coordR + direction[control][1];
					if (fcoordL < 8 && fcoordL >= 0 && fcoordR < 8 && fcoordR >= 0 && map[fcoordL][fcoordR] != 1) {
						coordL += direction[control][0];
						coordR += direction[control][1];
						map[coordL][coordR] = 1;
						flag++;
						step = flag;
						break;
					}
					else {
						if (control < 8) {
							control++;
						}
						else {
							break;
						}
					}
				}
			}
			else {
				break;
			}
		}
	}
	//走完时
	else {
		cout << "第" << step << "步的走法为" << "[" << direction[control][0] << "," << direction[control][1] << "]" << endl;
	}
}
int main() {
	//初始化棋盘
	for (int i = 0; i < 8; i++) {
		for (int j = 0; j < 8; j++) {
			map[i][j] = 0;
		}
	}
	scanf_s("%d %d", &coordL, &coordR);
	//走起
	solve();
	return 0;
}
「已注销」 2019-10-29
  • 打赏
  • 举报
回复
8*8的数组,只要大于0小于8就行 那个函数里面判断是否可以走的那个if太长了,刚才我没试,无法读取值,所以无法比较,然后就退了
引用 7 楼 wowpH 的回复:
额,你直接告诉我输入多少吧。我试了好几个都不行。
wowpH 2019-10-29
  • 打赏
  • 举报
回复
wowpH 2019-10-29
  • 打赏
  • 举报
回复
额,你直接告诉我输入多少吧。我试了好几个都不行。
「已注销」 2019-10-29
  • 打赏
  • 举报
回复
引用 3 楼 wowpH 的回复:
经测试,代码无法运行(输入8 8都不行)。思路还没看。
我都注释了没有设置检测,总共8*8的数组,你给我输个8
「已注销」 2019-10-29
  • 打赏
  • 举报
回复
输出之后运行多久能出来就看你电脑了,XP起码一天
wowpH 2019-10-29
  • 打赏
  • 举报
回复
经测试,代码无法运行(输入8 8都不行)。思路还没看。
「已注销」 2019-10-29
  • 打赏
  • 举报
回复
引用 1 楼 wowpH 的回复:
你这个输入压根儿没用。。。我输入半天。
你告诉我你输入了啥
wowpH 2019-10-29
  • 打赏
  • 举报
回复
你这个输入压根儿没用。。。我输入半天。
1.算法是程序的灵魂,优秀的程序在对海量数据处理时,依然保持高速计算,就需要高效的数据结构和算法支撑。2.网上数据结构和算法的课程不少,但存在两个问题:1)授课方式单一,大多是照着代码念一遍,数据结构和算法本身就比较难理解,对基础好的学员来说,还好一点,对基础不好的学生来说,基本上就是听天书了2)说是讲数据结构和算法,但大多是挂羊头卖狗肉,算法讲的很少。 本课程针对上述问题,有针对性的进行了升级 3)授课方式采用图解+算法游戏的方式,让课程生动有趣好理解 4)系统全面的讲解了数据结构和算法, 除常用数据结构和算法外,还包括程序员常用10大算法:二分查找算法(非递归)、分治算法、动态规划算法、KMP算法、贪心算法、普里姆算法、克鲁斯卡尔算法、迪杰斯特拉算法、弗洛伊德算法马踏棋盘算法。可以解决面试遇到的最短路径、最小生成树、最小连通图、动态规划等问题及衍生出的面试题,让你秒杀其他面试小伙伴3.如果你不想永远都是代码工人,就需要花时间来研究下数据结构和算法。教程内容:本教程是使用Java来讲解数据结构和算法,考虑到数据结构和算法较难,授课采用图解加算法游戏的方式。内容包括: 稀疏数组、单向队列、环形队列、单向链表、双向链表、环形链表、约瑟夫问题、栈、前缀、中缀、后缀表达式、中缀表达式转换为后缀表达式、递归与回溯、迷宫问题、八皇后问题、算法的时间复杂度、冒泡排序、选择排序、插入排序、快速排序、归并排序、希尔排序、基数排序(桶排序)、堆排序、排序速度分析、二分查找、插值查找、斐波那契查找、散列、哈希表、二叉树、二叉树与数组转换、二叉排序树(BST)、AVL树、线索二叉树、赫夫曼树、赫夫曼编码、多路查找树(B树B+树和B*树)、图、图的DFS算法和BFS、程序员常用10大算法、二分查找算法(非递归)、分治算法、动态规划算法、KMP算法、贪心算法、普里姆算法、克鲁斯卡尔算法、迪杰斯特拉算法、弗洛伊德算法马踏棋盘算法。学习目标:通过学习,学员能掌握主流数据结构和算法的实现机制,开阔编程思路,提高优化程序的能力。

69,371

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧