1330:【例8.3】最少步数

探讨了在一个100x100的棋盘上,马如何利用日和田两种走法从任意起点到达左上角(1,1)点的最短步数。通过广度优先搜索算法(BFS),遍历所有可能的方向,最终找到从给定起点到目标点的最少步数。

1330:【例8.3】最少步数

【题目描述】

在各种棋中,棋子的走法总是一定的,如中国象棋中马走“日”。有一位小学生就想如果马能有两种走法将增加其趣味性,因此,他规定马既能按“日”走,也能如象一样走“田”字。他的同桌平时喜欢下围棋,知道这件事后觉得很有趣,就想试一试,在一个(100×100)的围棋盘上任选两点A、B,A点放上黑子,B点放上白子,代表两匹马。棋子可以按“日”字走,也可以按“田”字走,俩人一个走黑马,一个走白马。谁用最少的步数走到左上角坐标为(1,1)的点时,谁获胜。现在他请你帮忙,给你A、B两点的坐标,想知道两个位置到(1,1)点可能的最少步数。
【输入】
A、B两点的坐标。
【输出】
最少步数。
【输入样例】

12 16
18 10

【输出样例】

8
9

解题思路:

这题想到的就是bfs,大致就是用队列将每一种结果保存,然后依次出队列,找到目标状态。一共有12个不同的方向可以选择,用一个二维数组保存方向向量,用另一个二维数组来记录棋盘上的点是否被走过。
代码:

#include<iostream>
#include<queue>
using namespace std;
const int M = 105;
bool mp[M][M] = { false };//整个棋盘的信息
int vis[12][2] = { {2,1},{2,2},{1,2},{-1,2},{-2,2},{-2,1},{-2,-1},{-2,-2},{-1,-2},{1,-2},{2,-2},{2,-1} };//vis为方向向量,一个有12个方向
struct crood
{
	int x, y;//坐标
	int step;//走到该点所需要得步数
};//crood记录每个点的位置以及多少步走到该点
int ans;
void bfs(int x,int y)
{
	queue<crood>que;//队列保存状态
	crood now, next;//now是当前的状态,next表示下一步的状态
	now.step = 0;
	now.x = x;
	now.y = y;
	mp[x][y] = true;
	que.push(now);//当前状态入队
	while (!que.empty())
	{
		now = que.front();//更新状态
		que.pop();//出队
		for (int i = 0; i < 12; i++)
		{
			next.x = now.x + vis[i][0];
			next.y = now.y + vis[i][1];
			next.step = now.step + 1;//走一步
			if (next.x == 1 && next.y == 1)//达到目标
			{
				ans = next.step;
				return;
			}
			if ((!mp[next.x][next.y]) && next.x > 0 && next.x < 101 && next.y>0 && next.y < 101)
			//该点没被走过,一定要注意是否越界
			{
				mp[next.x][next.y] = true;//标记已走
				que.push(next);//入队
			}
		}
	}
}
int main()
{
	int x, y;
	while (cin >> x >> y)
	{
		memset(mp, false, sizeof(mp));
		bfs(x, y);
		cout << ans << endl;
	}
	return 0;
}

bfs与dfs总结与详解

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值