当前位置: 首页 > news >正文

数据结构栈的使用——马踏棋盘

题目

设计一个国际象棋的马踏遍棋盘的演示程序。

将马随机放在国际象棋棋盘8×8棋盘 map[8][8]的某个方格中,马按照走棋规则进行移动。要求每个方格只进入一次,走遍棋盘上全部64个方格。编制程序,求出马的行走路线,并按求出的行走路线,将数字1,2,.......,64依次填入一个8×8的方阵,输出之。可自行指定一个马的初始位置(x,y)。下面图中显示了马位于方格位置中8个可移动的位置。

每次在多个可走位置中选择其中一个进行试探,其余未曾试探过的可走位置必须用适当的结构妥善管理,以备试探失败时“回溯”(悔棋)使用。

 结构体的定义:

#define MAX 64
typedef struct 	//存储马可以踏成功的位置 
{
	int x,y;	 
}postion;

typedef struct Zhan		//栈就是存储已经成功踏入的点 
{
	postion a[MAX];		//存位置 
	int top;	//栈顶位置 
}Zhan;		//结构体别名 

栈需要进行初始化,初始化函数的代码如下:

void InitZhan(Zhan *s)	//栈的初始化 
{
	s->top=-1;
}

压栈和退栈的操作与简单栈的操作相同代码如下所示:

int Push(Zhan *s,postion x)	//存数据的函数 
{	
	if(s->top==MAX-1)	//判断栈有没有存满也就是马有没有把棋盘踏完 
		return 0;	
	else		//没有踏完 
	{
		s->top++;	//栈顶先加 
		s->a[s->top]=x;	// 存入栈里 
		return 1;	
	 } 
}

int Pop(Zhan *s)	//如果马已经无路可走就退回上一步,然后继续判断其他的路 
{
	if(s->top==-1)	//栈有没有空 
	return 0;
	else	//没空的时候就让栈顶减1 
	{
		s->top--;
		return 1;
	}
}

在马进行踏迷宫的时候需要有一个函数判断我们存储数据的栈中的元素是否已经全部退出完成,其中的代码如下所示:

int IsEmpty(Zhan *s)	//栈有没有空的一个函数 
{
	if(s->top==-1)
		return 1;
	return 0;
}

在找马可以走的位置还需要有一个得到栈顶位置的函数,其中代码如下:

postion Gettop(Zhan *s)	//找到栈顶的位置在哪 
{
	postion x;
	x=s->a[s->top];
	return x;
}

在该程序中需要定义两个[8][8]的数组初始值为0,一个用来存储马在其中踏的第几次,另一个则用来判断马有没有将其走过。和马可以走的八个位置的数组,还需定义一个标记变量,用来判断马有没有踏完棋盘。(其中全为全局变量,还需定义一个栈)

定义如下所示:

int map[8][8]={0};	//初始化棋盘 
int book[8][8]={0};	//存储有没有走 
int next[8][2]={-2,1,-1,2,1,2,2,1,2,-1,1,-2,-1,-2,-2,-1};	//
int flag=0;	//一个变量判断有没有走完 
Zhan s;	//先定义一个栈 

然后下来就是该程序的核心代码,也就是马该怎么走,该函数包含三个参数,两个用来存储马的坐标位置,第三个参数用来存储马走了第几步。在函数中首先判断马有没有将棋盘走完,如果走完了则在其中将判断变量值设置为1,且定义一个次数变量,加一个循环其停止条件则是该栈为空,当栈一直不为空时则让一个结构体存储栈顶的数据,然后进行退栈操作随后将map中的栈顶位置存储为最后一个位置,依次类推存储马走的位置。然后当栈为空时退出循环打印马走的棋盘。如果马没有将棋盘走完则让马的当前位置判断周围的八个点是否可以走,如果可以走则标记该点已走过然后将数据存入栈中,如果走不了则继续进行循环直到八个点都不可以走之后则将栈元素退出然后标记值设置为0,再次调用该函数让马继续走。

核心代码如下所示:

void Run(int x,int y,int step)	//马走的函数 
{
	if(step==64)	//判断棋盘走没走完,走完就输出地图 
	{
		flag=1;	//走完变量为1 
		int Count=0;	//走的次数 
		while(!IsEmpty(&s))	//判断栈有没有空 
		{
			postion n =Gettop(&s);	// 让n获得栈顶的位置 
			Pop(&s);	//退出一个位置,为了得到下一个位置所以得到栈顶后需要退出栈顶的元素 
			map[n.x][n.y]=64-(Count++);	//将栈退出的次数存入地图中 
		}
		for(int i=0;i<8;i++)	//打印棋盘 
		{
			for(int j=0;j<8;j++)
			{
					cout<<map[i][j]<<" "; 	//相当于C语言的printf 
			}
			cout<<endl;	//相当于\n 
		}
		return ;
	}
	for(int i=0;i<8;i++)	//马当前可以走的8个位置 
	{	
		int x1=x+next[i][0];	//找到马走的下一步的x位置	
		int y1=y+next[i][1];	//找到马走的下一步的y位置	
		if(x1<0||x1>7||y1<0||y1>7||book[x1][y1]==1)	//判断马的下一步有没有超过棋盘的位置,如果超过了则继续返回循环 
		{
			continue;
		}
		if(book[x1][y1]==0)	//判断马的下一步走了没走 
		{
			book[x1][y1]=1;	//马已经走了这一步 
			postion p;	//存x,y的结构体 ,把马当前的位置存在p中 
			p.x=x1;	
			p.y=y1;
			Push(&s,p);	//把结构体p放在栈中 
			Run(x1,y1,step+1);	//递归下一步, 
			if(flag)	return ;	// 如果已经走完直接出函数 
			book[x1][y1]=0;	//把当前马的位置设置为0,也就是没有走 
			Pop(&s);	//把存储进去的位置退出来 
		}
	}
	return ;
}

整体的完整代码如下所示:

#include<iostream>	//include<stdio.h> 
#include<stdlib.h>	//开辟空间的头文件malloc 
#include<iomanip>	//不写 
using namespace std;	//可以不写 

#define MAX 64
typedef struct 	//存储马可以踏成功的位置 
{
	int x,y;	 
}postion;

typedef struct Zhan		//栈就是存储已经成功踏入的点 
{
	postion a[MAX];		//存位置 
	int top;	//栈顶位置 
}Zhan;		//结构体别名 

void InitZhan(Zhan *s)	//栈的初始化 
{
	s->top=-1;
}

int Push(Zhan *s,postion x)	//存数据的函数 
{	
	if(s->top==MAX-1)	//判断栈有没有存满也就是马有没有把棋盘踏完 
		return 0;	
	else		//没有踏完 
	{
		s->top++;	//栈顶先加 
		s->a[s->top]=x;	// 存入栈里 
		return 1;	
	 } 
}

int Pop(Zhan *s)	//如果马已经无路可走就退回上一步,然后继续判断其他的路 
{
	if(s->top==-1)	//栈有没有空 
	return 0;
	else	//没空的时候就让栈顶减1 
	{
		s->top--;
		return 1;
	}
}

int IsEmpty(Zhan *s)	//栈有没有空的一个函数 
{
	if(s->top==-1)
		return 1;
	return 0;
}

postion Gettop(Zhan *s)	//找到栈顶的位置在哪 
{
	postion x;
	x=s->a[s->top];
	return x;
}

int map[8][8]={0};	//初始化棋盘 
int book[8][8]={0};	//存储有没有走 
int next[8][2]={-2,1,-1,2,1,2,2,1,2,-1,1,-2,-1,-2,-2,-1};	//
int flag=0;	//一个变量判断有没有走完 
Zhan s;	//先定义一个栈 

void Run(int x,int y,int step)	//马走的函数 
{
	if(step==64)	//判断棋盘走没走完,走完就输出地图 
	{
		flag=1;	//走完变量为1 
		int Count=0;	//走的次数 
		while(!IsEmpty(&s))	//判断栈有没有空 
		{
			postion n =Gettop(&s);	// 让n获得栈顶的位置 
			Pop(&s);	//退出一个位置,为了得到下一个位置所以得到栈顶后需要退出栈顶的元素 
			map[n.x][n.y]=64-(Count++);	//将栈退出的次数存入地图中 
		}
		for(int i=0;i<8;i++)	//打印棋盘 
		{
			for(int j=0;j<8;j++)
			{
					cout<<map[i][j]<<" "; 	//相当于C语言的printf 
			}
			cout<<endl;	//相当于\n 
		}
		return ;
	}
	for(int i=0;i<8;i++)	//马当前可以走的8个位置 
	{	
		int x1=x+next[i][0];	//找到马走的下一步的x位置	
		int y1=y+next[i][1];	//找到马走的下一步的y位置	
		if(x1<0||x1>7||y1<0||y1>7||book[x1][y1]==1)	//判断马的下一步有没有超过棋盘的位置,如果超过了则继续返回循环 
		{
			continue;
		}
		if(book[x1][y1]==0)	//判断马的下一步走了没走 
		{
			book[x1][y1]=1;	//马已经走了这一步 
			postion p;	//存x,y的结构体 ,把马当前的位置存在p中 
			p.x=x1;	
			p.y=y1;
			Push(&s,p);	//把结构体p放在栈中 
			Run(x1,y1,step+1);	//递归下一步, 
			if(flag)	return ;	// 如果已经走完直接出函数 
			book[x1][y1]=0;	//把当前马的位置设置为0,也就是没有走 
			Pop(&s);	//把存储进去的位置退出来 
		}
	}
	return ;
}

int main()
{
	InitZhan(&s);	//初始化 
	int x,y;	
	cout<<"请输入马的初始位置->";	//printf 
	cin>>x>>y;		//相当于c语言的scanf 
	map[x][y]=1;	//先存储初始位置 
	book[x][y]=1;	//马已经走过存1 
	Run(x,y,1); 	//运行初始位置时马走的步 
	return 0;
}

最终运行的结果如下图所示:

 输入其他值可能会导致运行变慢因为马踏的时候可能会存在很多次回溯所以运行的时间会变的很长,甚至有些位置可能不会踏完棋盘。

相关文章:

  • 网络知识之跨区域网络的通信
  • C#三层架构
  • 动态内存开辟(上)
  • 【云原生】阿里云容器镜像服务产品ACR EE之国内外场景应用模拟
  • html之网页结构
  • 手把手教你使用LabVIEW人工智能视觉工具包快速实现传统Opencv算子的调用(含源码)
  • Python小知识点
  • 目标检测 YOLOv5 - 最新版本v6.2模型在瑞芯微 Rockchip设备上运行的方案
  • Android 项目必备(三十)-->从 0 到 1 开发一个属于自己的 App
  • led灯珠型号及使用参数
  • MYSQL介绍——数据库的增删改及常用函数
  • 线性单功能PEG试剂甲氧基-聚乙二醇-丙烯酰胺,mPEG-Acrylamide,mPEG-ACA
  • 洛谷P3694
  • b站pink老师Echarts数据可视化笔记
  • 计算机三级数据库运行维护与优化(四)、合理使用索引、数据库存储结构和存取方法优化、完全规范化、索引的使用原则、、网络优化、监控内容、物化视图
  • Android组件 - 收藏集 - 掘金
  • Git初体验
  • HTML中设置input等文本框为不可操作
  • MySQL主从复制读写分离及奇怪的问题
  • PHP面试之三:MySQL数据库
  • PyCharm搭建GO开发环境(GO语言学习第1课)
  • Web Storage相关
  • 闭包,sync使用细节
  • 回顾 Swift 多平台移植进度 #2
  • 基于Android乐音识别(2)
  • 解决iview多表头动态更改列元素发生的错误
  • 猫头鹰的深夜翻译:Java 2D Graphics, 简单的仿射变换
  • 前嗅ForeSpider采集配置界面介绍
  • 容器化应用: 在阿里云搭建多节点 Openshift 集群
  • 如何用Ubuntu和Xen来设置Kubernetes?
  • 使用docker-compose进行多节点部署
  • 算法-插入排序
  • 跳前端坑前,先看看这个!!
  • 我这样减少了26.5M Java内存!
  • 云栖大讲堂Java基础入门(三)- 阿里巴巴Java开发手册介绍
  • 3月7日云栖精选夜读 | RSA 2019安全大会:企业资产管理成行业新风向标,云上安全占绝对优势 ...
  • ​Z时代时尚SUV新宠:起亚赛图斯值不值得年轻人买?
  • ​卜东波研究员:高观点下的少儿计算思维
  • ​软考-高级-系统架构设计师教程(清华第2版)【第20章 系统架构设计师论文写作要点(P717~728)-思维导图】​
  • # centos7下FFmpeg环境部署记录
  • #HarmonyOS:Web组件的使用
  • #NOIP 2014#day.2 T1 无限网络发射器选址
  • (20)目标检测算法之YOLOv5计算预选框、详解anchor计算
  • (delphi11最新学习资料) Object Pascal 学习笔记---第5章第5节(delphi中的指针)
  • (pojstep1.1.2)2654(直叙式模拟)
  • (二)JAVA使用POI操作excel
  • (附表设计)不是我吹!超级全面的权限系统设计方案面世了
  • (附源码)php新闻发布平台 毕业设计 141646
  • (附源码)ssm旅游企业财务管理系统 毕业设计 102100
  • (汇总)os模块以及shutil模块对文件的操作
  • (论文阅读笔记)Network planning with deep reinforcement learning
  • (每日持续更新)jdk api之FileFilter基础、应用、实战
  • (四)库存超卖案例实战——优化redis分布式锁
  • (原創) 如何動態建立二維陣列(多維陣列)? (.NET) (C#)
  • (原創) 如何解决make kernel时『clock skew detected』的warning? (OS) (Linux)