P1443 马的遍历-洛谷(BFS)

原题链接:

https://www.luogu.com.cn/problem/P1443

题目描述

有一个 n×m 的棋盘,在某个点 (x,y) 上有一个马,要求你计算出马到达棋盘上任意一个点最少要走几步。

输入格式

输入只有一行四个整数,分别为 n, m, x, y。

输出格式

一个n×m 的矩阵,代表马到达某个点最少要走几步(左对齐,宽 5 格,不能到达则输出 −1)。

输入输出样例:

输入#1

3 3 1 1

输出#1

0    3    2
3    -1    1
2    1    4

提示

数据规模与约定
对于全部的测试点,保证1 ≤ x ≤n ≤ 400,1 ≤ y ≤ m ≤ 400。

思路方法:

这题需要采用广度优先搜索的策略(BFS),先定义一个标记数组,,记录马行走过的点 ,然后定义一个答案数组,记录马到达点的最小步数 ,再定义两个队列,记录可行点的坐标。首先将马的当前位置作为起点,进行标记和记录步数,然后当前点进入队列。然后进入一个二维循环,外层循环判断队列是否为空,内层循环依次遍历马的8个落点(别告诉我马走八方你都不知道🙃),可行的落点进行标记并记录步数,然后可行的点要进入队列中。8个方向判断完后,当前的点需要出栈。最终直到栈为空结束。

AC代码:

#include <bits/stdc++.h>
using namespace std;

int n, m, x, y;
queue<int>q,q1;//分别表示当前的行和列 
vector<vector<int> >a(401, vector<int>(401));//标记数组,记录马行走过的点 
vector<vector<int> >b(401, vector<int>(401, -1));//答案数组,记录马到达点的最小步数 
int dx[8]={-2,-2,2,2,1,-1,1,-1};//压缩马行走的8个方向 
int dy[8]={-1,1,-1,1,2,-2,-2,2};

void BFS(){
	while(!q.empty()){//队列中有元素就一直循环 
		for(int i = 0; i < 8; i++){//依次判断马的8个方向是否可走 
			int xx = q.front() + dx[i];//记录行走后的位置 
			int yy = q1.front() + dy[i];
			if(xx > 0 && xx <= n && yy > 0 && yy <= m && !a[xx][yy]){//判断是否越界,是否被访问过 
				a[xx][yy] = 1;//标记为访问过 
				b[xx][yy] = b[q.front()][q1.front()] + 1;//当前的步数记录为前一个点的步数 +1 
				q.push(xx);//将当前点入队 
				q1.push(yy);
			}
		}
		q.pop();//当前点的8个方向判断完毕,当前点出队 
		q1.pop();
	}
}
int main(){
	cin>>n>>m>>x>>y;
	q.push(x);//将当前位置作为起点 
	q1.push(y);
	a[x][y] = 1;//起点标记为走过 
	b[x][y] = 0;//起点的步数为0 
	BFS();
	for(int i = 1; i <= n; i++){//输出答案 
		for(int j = 1; j <= m; j++){
			printf("%-5d",b[i][j]);
		}
		printf("\n");
	}
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

WTY2002

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

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

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

打赏作者

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

抵扣说明:

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

余额充值