马踏棋盘问题(C-数据结构)

2023-11-16

题目

在8×8的国际象棋棋盘中,给出马的初始位置,求出马踏遍棋盘每个位置的路线图(棋盘中每个位置只能走一次)

思路

国际象棋中,马走的规则和中国象棋相似,为斜两格行走(即向任意方向走两格,再向与前面行走方向垂直的方向走一格)
每个位置最多可以向八个方向行走,用回溯算法的话,我们会对每个方向进行尝试,走不通则进行回溯,知道可以走通时,输出路线图;我们这里采用贪心算法,在当前位置时,我们对每个方向的位置进行检测,检测他们可以走的方向数量,然后对这些方向数量进行排序;优先向方向数量少的方向走,当遇到当前位置的每个方向都走不通时(即走过的方向数达到上限)我们进行出栈操作,然后回到上一个位置,按照以上方法持续进行,直到走过所有的位置时输出路线图。

代码

#include <stdio.h>
#define ROW 8
#define COL 8
#define MAXSTEP 64

typedef struct horse {
	int x;	//横坐标 
	int y;	//纵坐标 
	int dir; //方向 
}Horse;

int top; //栈顶 
Horse horse[MAXSTEP];
int chess[ROW+1][COL+1]; //存储期盼对应路线 
int dir[8][2] = {{2,-1},{-2,-1},{-2,1},{2,1},{1,-2},{-1,-2},{-1,2},{1,2}};

void Init(); //初始化数据 
void push(int x,int y); //入栈 
void pop();// 出栈
void mark_chess(int x,int y);// 在棋盘上标记路线 
void print_chess();// 打印棋盘上的路线
void run();// 核心(贪心算法)

int main()
{
	int x,y;
	while(1){
		printf("请输入马的初始位置 x(1-8) y(1-8):");
		scanf("%d %d",&x,&y);
		if(x<1||x>ROW||y<=0||y>COL){
			printf("初始数据错误,请重新输入 x(1-8) y(1-8)");
		} else{
			break;
		}		
	}
	Init();
	push(x,y);
	mark_chess(x,y);
	run();
}


//初始化数据 
void Init()
{
	for(int i=0;i<MAXSTEP;i++){
		horse[i].x=0;
		horse[i].y=0;
		horse[i].dir=-1;
	}
	for(int i=0;i<=ROW;i++){
		for (int j=0;j<=COL;j++){
			chess[i][j]=0;
		}
	}
	top=-1;
}
//入栈 
void push(int x,int y)
{
	horse[++top].x=x;
	horse[top].y=y;
	horse[top].dir=-1;
 } 
// 出栈
void pop()
{
	horse[top].x=0;
	horse[top].y=0;
	horse[top].dir=-1;
	top--;
 } 
 
// 在棋盘上标记路线 
 void mark_chess(int x,int y)
 {
 	chess[y][x] = top + 1;
 }
 
// 打印棋盘上的路线 
 void print_chess()
 {
 	printf("马在棋盘上的路线图:\n"); 
 	for(int i=1;i<=ROW;i++){
		for (int j=1;j<=COL;j++){
			printf("%4d",chess[i][j]);
		}
		printf("\n");
	}
 }
 
// 核心(贪心算法) 
 void run() 
 {
 	
 	int x_now,y_now;
 	while(1){
 		//所有地方已经过 
 		if(top+1>=MAXSTEP){
 			print_chess(); 
 			break;
		 }
	    //当前位置 
		x_now=horse[top].x;
		y_now=horse[top].y;
		
		//记录对应方向可以走几个方向		
		int next[ROW]={0};
		for(int i=0;i<ROW;i++){
			int x_next=x_now+dir[i][0];
			int y_next=y_now+dir[i][1];
			if(x_next>0&&x_next<=COL&&y_next>0&&y_next<=ROW&&chess[y_next][x_next]==0){
				for(int j=0;j<ROW;j++){
					int x_next_next=x_next+dir[j][0];
					int y_next_next=y_next+dir[j][1];
					if(x_next_next>0&&x_next_next<=COL&&y_next_next>0&&y_next_next<=ROW&&chess[y_next_next][x_next_next]==0){
						next[i]++;
					}
				} 
			}
		}
		//对各个方向可以走的方向数进行排序,先走方向数小的方向		
		int t=ROW+1;
		int real_next[ROW]={0};
		int index=0;
		for(int i=0;i<ROW;i++){
			t=ROW+1;
			for(int j=0;j<ROW;j++){
				if(next[j]<t){
					real_next[i]=j;
					t=next[j];			
					index=j;
				}
			}
			next[index]=ROW+1;
		}
		//开始走 
		int dir_now=0;
		for(dir_now=horse[top].dir+1;dir_now<ROW;dir_now++){
			int x_real=x_now+dir[real_next[dir_now]][0];
			int y_real=y_now+dir[real_next[dir_now]][1];
			horse[top].dir++;
			if(x_real>0&&x_real<=COL&&y_real>0&&y_real<=ROW&&chess[y_real][x_real]==0){
				push(x_real,y_real);
				mark_chess(x_real,y_real);
				break;
			}
		}
		//当前位置走过的方向数到达上限,此时此路不通,进行回退(出栈) 
		if(horse[top].dir>=7){
			chess[horse[top].y][horse[top].x] = 0;
			pop();
		}
	}
 }
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

马踏棋盘问题(C-数据结构) 的相关文章

  • D - Loong and Takahashi (经典模拟绕圈)

    题目 https atcoder jp contests abc335 tasks abc335 d 思想 令 flag 0 1 2 3 分别代表四个方向右 下 左 上 然后判断下一步是否超过边界或者被填充过 如果是 就换方向 最后输出 代
  • 华为OD机试真题-字符串拼接-2023年OD统一考试(C卷)

    题目描述 给定M 0
  • 【质量-弹簧-阻尼系统】基于脉冲响应约束的子空间辨识研究(Matlab代码实现)

    欢迎来到本博客 博主优势 博客内容尽量做到思维缜密 逻辑清晰 为了方便读者 座右铭 行百里者 半于九十 本文目录如下 目录 1 概述 2 运行结果 3 参考文献 4 Matlab代码 数据 文章
  • 关于整型提升与截断的一道题目

    关于整型提升与截断 可以看我的博客 C语言 整型提升 c语言整形提升 CSDN博客 C语言 截断 整型提升 算数转换练习 c语言unsigned CSDN博客 一 题目 二 题解 char a 101截断 由于101是整型数据 需要32比特
  • 小白刷题之图形输出

    拓展 string string int num char ch num表示打印字符个数 ch表示打印内容 include
  • 排序:计数排序

    一 概念 计数排序是非比较排序 是对哈希直接定址法的变形应用 二 思想 利用数组统计相同数据出现的次数 例如整型数据m出现n次 就在数组m位置记录数据为n 最后从头遍历数组打印数据即可 通俗来讲就是 数组下标即为数据 下标所指位置的值即为数
  • 2024年华为OD机试真题-小明找位置-Java-OD统一考试(C卷)

    题目描述 小朋友出操 按学号从小到大排成一列 小明来迟了 请你给小明出个主意 让他尽快找到他应该排的位置 算法复杂度要求不高于nLog n 学号为整数类型 队列规模 lt 10000 输入描述 1 第一行 输入已排成队列的小朋友的学号 正整
  • c语言学生管理系统

    创建结构体里面包含学生的各种信息 struct xs int xh char xm 20 int gs yy wl double pj struct xs next 创建菜单 void menu printf n n printf 学生管理
  • 206.翻转链表

    翻转链表 力扣 LeetCode 官网 全球极客挚爱的技术成长平台 备战技术面试 力扣提供海量技术面试资源 帮助你高效提升编程技能 轻松拿下世界 IT 名企 Dream Offer https leetcode cn problems re
  • 华为OD机试2024年最新题库(C++)

    我是一名软件开发培训机构老师 我的学生已经有上百人通过了华为OD机试 学生们每次考完试 会把题目拿出来一起交流分享 重要 2024年1月 5月 考的都是OD统一考试 C卷 题库已经整理好了 命中率95 以上 这个专栏使用 C 解法 问1 考
  • 带头双向循环链表基础

    带头双向循环链表基础 销毁 销毁 void ListDestory ListNode phead void ListDestory ListNode phead assert phead ListNode cur phead gt next
  • 华为OD机试真题-分配土地-Python-OD统一考试(C卷)

    题目描述 从前有个村庄 村民们喜欢在各种田地上插上小旗子 旗子上标识了各种不同的数字 某天集体村民决定将覆盖相同数字的最小矩阵形的土地的分配给为村里做出巨大贡献的村民 请问 此次分配土地 做出贡献的村民中最大会分配多大面积 输入描述 第一行
  • 矩阵基本操作2

    题目描述 问题描述 将方阵 n 行n列 n lt 100 置成下三角矩阵 主对角线右上角数字全部清零 输入格式 第一行输入n 接下来的n行每行n列 表示矩阵的数值 用空格隔开 输出格式 n行n列下三角矩阵 每个数字3个占位符 左对齐 输入样
  • ​LeetCode解法汇总82. 删除排序链表中的重复元素 II

    目录链接 力扣编程题 解法汇总 分享 记录 CSDN博客 GitHub同步刷题项目 https github com September26 java algorithms 原题链接 力扣 LeetCode 描述 给定一个已排序的链表的头
  • 毕业设计- 基于深度学习的小样本时间序列预测算法 - Attention

    目录 前言 课题背景与意义 课题实现 一 数据集 二 设计思路 三 相关代码示例 最后 前言 大四是整个大学期间最忙碌的时光 一边要忙着准备考研 考公 考教资或者实习为毕业后面临的就业升学做准备 一边要为毕业设计耗费大量精力 近几年各个学校
  • 做大模型也有1年多了,聊聊这段时间的感悟!

    自ChatGPT问世以来 做大模型也有1年多了 今天给大家分享这一年后的感悟 过去一年应该是AI圈最万千瞩目的一年了 大家对大模型 OpenAI ChatGPT AI Native Agent这些词投入了太多的关注 以至于有一年的时间好像经
  • 【牛客周赛Round 27】题目讲解

    题目一 小红的二进制删数字 小红拿到了一个二进制字符串 s 她可以删掉其中的一些字符 使得最终该字符串为一个2的幂 即可以表示为 2 k 形式的数 小红想知道 自己最少删几个字符可以达成 请你编写一个函数返回这个答案 具体思路 看到这道题目
  • 机器学习算法实战案例:Informer实现多变量负荷预测

    文章目录 机器学习算法实战案例系列 答疑 技术交流 1 实验数据集 2 如何运行自己的数据集 3 报错分析 机器学习算法实战案例系
  • 「优选算法刷题」:移动零

    嗨 这个假期罗根开始接触了算法 在为今年的蓝桥杯做准备 所以 开个新专栏 记录记录自己做算法题时的心得 一 题目 给定一个数组 nums 编写一个函数将所有 0 移动到数组的末尾 同时保持非零元素的相对顺序 请注意 必须在不复制数组的情况下
  • 【GRNN-RBFNN-ILC算法】【轨迹跟踪】基于神经网络的迭代学习控制用于未知SISO非线性系统的轨迹跟踪(Matlab代码实现)

    欢迎来到本博客 博主优势 博客内容尽量做到思维缜密 逻辑清晰 为了方便读者 座右铭 行百里者 半于九十 本文目录如下 目录 1 概述 2 运行结果 2 1 第1部分 2 2 第2部分

随机推荐

  • 华为VS谷歌:万物互联,谁主沉浮?

    一 一周两套操作系统发布 6月2日 华为通过直播形式举行了鸿蒙HarmonyOS 2及华为全场景新品发布会 关于该发布会的详细内容老猿在 鸿蒙最新功能及承载设备详解 HarmonyOS 2及华为全场景新品发布会全纪录 进行了详细介绍 在此不
  • 【科普】一文读懂以太网PHY芯片

    物理层器件PHY Physical Layer Interface Devices 是将各网元连接到物理介质上的关键部件 负责完成互连参考模型 OSI 第1层中的功能 即为链路层实体之间进行bit传输提供物理连接所需的机械 电气 光电转换和
  • 嵌入式中锁机制杂谈

    在之前的文章中有提到操作系统中锁机制一般依赖于硬件CPU提供的原子数据操作指令 如SWP TEST AND SET等原子原语实现 基于此 才能真正保证锁机制的有效实现 通过上面原子操作 我们比较容易实现所谓的自旋操作 原子性的原地循环判断条
  • np.random.choice用法

    np random choice a size replace p 其作用是按要求生成一个一维数组 a是生成一维数组的来源 可以是int类型 可以是数组 也可以是list size 为从a中抽取的个数 即生成数组的维度 replace 表示
  • 《数据库系统》课程之实验七 通过ODBC/JDBC转移异构数据库中数据

    注 查看全文请关注作者 或点击前往 数据库系统 课程之实验七 通过ODBC JDBC转移异构数据库中数据 数据库系统 课程之实验七 通过ODBC JDBC转移异构数据库中数据 1 实验目的 学会配置ODBC JDBC数据源 熟悉使用ODBC
  • QueryWrapper方法解释

    继承自 AbstractWrapper 自身的内部属性 entity 也用于生成 where 条件 及 LambdaQueryWrapper 可以通过 new QueryWrapper lambda 方法获取 queryWrapper lt
  • PyTorch实战——搭建PyTorch神经网络进行气温预测

    如果觉得我的分享对您的学习有帮助 可以点赞关注哈 谢谢哈 目录 编辑 一 理论部分 二 代码实战 1 导入模块 1 matplotlib inline 2 warnings filterwarnings ignore 2 读入数据 3 展示
  • 三极管电路共集、共基、共射的区别

    共集 共基 共射指的是电路 是三极管电路的连接状态而不是三极管 所谓 共 就是输入 输出回路共有的部分 其判断是在交流等效电路下进行的 共集电极电路 三极管的集电极接地 集电极是输入与输出的公共极 共基极电路 三极管的基极接地 基极是输入与
  • 安装ubuntu系统时给/home分配空间太小,导致训练模型时数据集无法存放,所以给/home增大100GGB的存储空间

    1 从Windows系统中分配出100GB的存储空间 2 制作gparted的U盘启动项 3 插入U盘 进入bios界面 选择U盘启动项 4 进入gparted软件界面进行存储空间的转移重新分配 5 Exit退出 重新进入linux系统 参
  • 微信小程序 WebSocket 端口号配置

    https blog liuguofeng com p 4630 服务端开启 WebSocket 使用 WorkerMan phpSocket io 开启的端口为 2120 访问为 ws wanaioa unetu net 2120 由于微
  • 基于 java Swing 客户端 和 Spring Boot/Spring Cloud & Alibaba 后台管理系统

    基于 java Swing 客户端 和 Spring Boot Spring Cloud Alibaba 后台管理系统 基于 java Swing 客户端 和 Spring Boot Spring Cloud Alibaba 后台管理系统
  • 【Java JDK的使用方法】

    Java JDK的使用方法 第一步 同时按住窗口键和R键 在弹出的运行框中输入cmd打开编译框 第二步 输入cd 空格 地址 可以查看桌面文本文档的属性 找到桌面地址 第三步 notepad 空格 文件名 java 新建java文件 第四步
  • 何为UNP技术?

    为了解决移动视频监控系统中的这种穿NAT型 宇视科技特意提出了UNP UniversalNetwork Passport 万能网络护照 技术 目前 针对监控系统穿越NAT设备 防火墙和安全网闸时 基本上都是使用引流方案 内部服务器 双网口方
  • C++ 调用tensorflow

    安装protobuf 3 6 安装依赖软件 sudo apt get install autoconf automake libtool curl make g unzip 克隆版本为3 6 0的protobuf源码 git clone b
  • 8.翻转子串

    题目描述 假定我们都知道非常高效的算法来检查一个单词是否为其他字符串的子串 请将这个算法编写成一个函数 给定两个字符串s1和s2 请编写代码检查s2是否为s1旋转而成 要求只能调用一次检查子串的函数 给定两个字符串s1 s2 请返回bool
  • 1-如何安装ROS

    如何安装ROS 大家好 我是如何 今天尝试在Ubantu下安装ROS Robot Operating System 测试环境 虚拟机VMware Ubantu20 04 准备步骤 添加ROS软件源 sudo sh c echo deb ht
  • C++之普通成员函数、虚函数以及纯虚函数的区别与用法要点

    C 之普通成员函数 虚函数以及纯虚函数的区别与用法要点 作者 luoweifu 字体 增加 减小 类型 转载 时间 2015 07 21 我要评论 本篇文章主要介绍了C 中的普通成员函数 虚函数以及纯虚函数 非常的详细 有需要的朋友可以参考
  • localstorage在uc无痕模式失效问题;

    做项目的时候发现localstorage在uc 无痕模式下失效 但是其他浏览器不会出现此类问题 补充 我的解决方案是使用cookie代替localstorage 但是有大神给出了解决方案我觉得非常nice 附 https www jians
  • Thrift快速入门和简单示例

    文章目录 Thrift介绍 Thrift的架构 Thrift的特性 开发速度快 接口维护简单 学习成本低 多语言 跨语言支持 稳定 广泛使用 快速入门例子 编译安装 创建Thrift IDL文件 通过编译器编译user thrift文件 生
  • 马踏棋盘问题(C-数据结构)

    题目 在8 8的国际象棋棋盘中 给出马的初始位置 求出马踏遍棋盘每个位置的路线图 棋盘中每个位置只能走一次 思路 国际象棋中 马走的规则和中国象棋相似 为斜两格行走 即向任意方向走两格 再向与前面行走方向垂直的方向走一格 每个位置最多可以向