洛谷 P1443 马的遍历

传送门:P1443 马的遍历

题目描述

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

输入格式

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

输出格式

一个 n×m 的矩阵,代表马到达某个点最少要走几步(不能到达则输出 −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)

解题思路

首先初始化ans数组,使其中的值全为-1。在方向数组中,要明白马在象棋中是怎么走的(此处不再介绍),第一次进入bfs时,记得将ans[x][y]设置为0,否则答案会出现错误。剩下的即为常规的BFS。

AC代码

#include<bits/stdc++.h>
using namespace std;
int n, m, x, y;
bool vis[1010][1010];//标记是否走过
int X[8] = { -1,-2,-2,-1,1,2,2,1 };
int Y[8] = { 2,1,-1,-2,2,1,-1,-2 };//8个方向
int ans[500][500];
void bfs()
{
	queue<pair<int, int> >q;//一个队列,存放坐标
	ans[x][y] = 0;//在(x,y)时走了0步
	q.push({ x,y });
	vis[x][y] = true;
	while (!q.empty())//在队列清空前一直执行该循环
	{

		pair<int, int> t = q.front();//获取最前面的元素
		int a = t.first;//取出队首
		int b = t.second;
		q.pop();//出队
		for (int i = 0; i < 8; i++)//8个方向,所以i<8
		{
			int u = a + X[i];//每次搜索后更新u,v,即为返回到上一个点
			int v = b + Y[i];
			if (u<1 || u>n || v<1 || v>m || vis[u][v])//如果出界,或者走过,直接跳过
				continue;
			vis[u][v] = true;//标记来过
			q.push({ u,v });//加入该点到队列中
			ans[u][v] = ans[a][b] + 1;//步数等于上一个可能点加1
		}
	}
}

int main()
{
	cin >> n >> m >> x >> y;
	memset(ans, -1, sizeof(ans));//初始化
	bfs();
	for (int i = 1; i <= n; i++) {
		for (int j = 1; j <= m; j++) {
			cout << setw(5) << ans[i][j];
		}
		cout << endl;
	}
	
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值