蓝桥 试题 算法训练 跳马 C++

问题描述

  一个8×8的棋盘上有一个马初始位置为(a,b),他想跳到(c,d),问是否可以?如果可以,最少要跳几步?

输入格式

  一行四个数字a,b,c,d。

输出格式

  如果跳不到,输出-1;否则输出最少跳到的步数。

样例输入

1 1 2 3

样例输出

1

数据规模和约定

  0<a,b,c,d≤8且都是整数。

这道题是经典的跳马搜素问题,可以选择BFS、DFS,BFS用时会小一点,毕竟DFS会回溯。由于博主的能力限制,本题会用DFS算法解答,注释附在代码上。

#include<iostream>
using namespace std;
int a,b,c,d;
int vis[10][10];//标记数组
int sum=64;//能到达的方法数,最大为8*8的格子全部走一遍,初始值为8*8,因为要找最小值
int dx[]={1,1,-1,-1,2,2,-2,-2};//方向数组X
int dy[]={2,-2,2,-2,1,-1,1,-1};//方向数组Y
void dfs(int x,int y,int dep){//dfs搜索
	if(dep>=sum){//如果当前步数大于最小步数则没有意义继续搜下去了,直接return
		return;
	}
	if(x==c&&y==d){//到达终点坐标(c,d)
		if(dep<sum){//判断步数是否小于最小步数,小于就更新
			sum=dep;
		}
		return;
	}
	for(int i=0;i<8;i++){//8个方向搜索
		int bx=x+dx[i];
		int by=y+dy[i];
		if(vis[bx][by]==1){//已经走过就不走了
			continue;
		}
		if(bx<=0||bx>8||by<=0||by>8){//不在边界范围内也不走
			continue;
		}//判断完说明该点可以走
		vis[bx][by]=1;//走就标记为走过
		dfs(bx,by,dep+1);//继续dfs
		vis[bx][by]=0;//回溯,解标记
	}
}
int main(){
	cin>>a>>b>>c>>d;
	vis[a][b]=1;//先把起点标记为走过,不然对后面搜索有影响
	dfs(a,b,0);//起点开始搜索
	if(sum==64){//如果sum还等于64,就说明sum就没有被更新过,也就是说根本到达不了终点
		cout<<-1;
	}else{
		cout<<sum;
	}
	return 0;
}

最后,博主也去提交验证了一下,AC了。

 本人小白一枚,能力有限,希望各位大佬理解。本文有错误的地方请指出,共同进步。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
运 用 贪 心 算 法 ,vc++ 语 言 编 写 , 可 单 步 输 出 结 果 【问题描述】 跳马问题也称骑士遍历、马踏棋盘问题:在8*8方格的棋盘上,从任意指定的方格出发,为象棋中的马寻找一条走遍棋盘每一格并且只经过一次的一条路径。 考虑国际象棋棋盘上某个位置的一只马,它是否可能只走63步,正好走过除起点外的其他63个位置各一次?如果有一种这样的走法,则称所走的这条路线为一条马的周游路线。试设计一个算法找出这样一条马的周游路线。 在一个8×8的方格棋盘中,按照国际象棋中马的行走规则从棋盘上的某一方格出发,开始在棋盘上周游,如果能不重复地走遍棋盘上的每一个方格, 这样的一条周游路线在数学上被称为国际象棋盘上马的哈密尔顿链。请你设计一个程序,从键盘输入一个起始方格的坐标,由计算机自动寻找并打印 【算法描述】 本题有较多方法求解,在此仅对回溯法进行分析。 一只马在棋盘的某一点,它可以朝8个方向前进,方向向量分别是:(2,1)、(2,-1)、(1,2)、(1,-2)、(-2,1)、(-2,-1)、(-1,2)、(-1,-2)。从中任选择一个方向前进,到达新的位置。在从新的位置选择一个方向前进,继续,直到无法前进为止。无法前进可能有如下原因:下一位置超出边界、下一位置已经被访问过。当马已经无法前进时,就回退到上一位置,从新选择一个新的方向前进;如果还是无法前进,就再回退到上一位置……

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

摆烂小白敲代码

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值