#E. 马的遍历
  • 板块学术版
  • 楼主du_jason
  • 当前回复3
  • 已保存回复3
  • 发布时间2025/1/20 10:39
  • 上次更新2025/1/20 10:53:26
查看原帖
#E. 马的遍历
1400224
du_jason楼主2025/1/20 10:39

前言 这是一道广搜的题,急的粉丝直接在目录跳到最后一节完整代

目录

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

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

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

输入输出样例 输入 #1复制

3 3 1 1 输出 #1复制

0 3 2
3 -1 1
2 1 4
说明/提示 数据规模与约定 对于全部的测试点,保证 1≤�≤�≤4001≤x≤n≤400,1≤�≤�≤4001≤y≤m≤400。

题目讲解 Bfs前的准备 第一步

我们需要讲题目已知条件和输入做好

定义:

const int dx[8] = {-1,-2,-2,-1,1,2,2,1};//方向数组 const int dy[8] = {2,1,-1,-2,2,1,-1,-2};//方向数组 queue<pair<int,int> > q; int n,m,x,y,f[10000][10000],vis[10000][10000];//vis是是否访问过的数 队列可以pair,也可以开结构体

const int dx[8] = {-1,-2,-2,-1,1,2,2,1};//方向数组 const int dy[8] = {2,1,-1,-2,2,1,-1,-2};//方向数组 struct node{ int x,y; }; queue q; int n,m,x,y,f[10000][10000],vis[10000][10000];//vis是是否访问过的数

输入不多说了

cin>>n>>m>>x>>y; BFS分解 第一步:

肯定是把第一个节点塞进队列并且将vis数组的位置标记为走过

f[x][y] = 0;
vis[x][y] = true;
q.push({x,y});

第二步:

我们要开始BFS了,在队列不为空时,我们需要将队头的的元素取出来

while(!q.empty()){
	int xx = q.front().first;
	int yy = q.front().second;
	q.pop();
}

第三步:

我们要向八个方向探索:

while(!q.empty()){
	int xx = q.front().first;
	int yy = q.front().second;
	q.pop();
	for(int i = 0;i<8;++i){
		int u = xx+dx[i],v = yy+dy[i];
	}
}

 第四步:

我们要筛掉不合法的方向,合法的方向将他在vis中标记一下,并且塞进队列

while(!q.empty()){
	int xx = q.front().first;
	int yy = q.front().second;
	q.pop();
	for(int i = 0;i<8;++i){
		int u = xx+dx[i],v = yy+dy[i];
		if(u<1||u>n||v<1||v>m||vis[u][v]) continue;
		vis[u][v] = true;
		q.push({u,v});
		f[u][v] = f[xx][yy]+1;
	}
}

好了,我们就BFS完了

Bfs后的剩余: 我们搜索完了需要输出数组

for(int i=1;i<=n;++i)
	for(int j=1;j<=m;++j)
	{
		cout<<f[i][j]<<" \n"[j==m];
	}

完整代码:

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

const int dx[8] = {-1,-2,-2,-1,1,2,2,1};//方向数组 

const int dy[8] = {2,1,-1,-2,2,1,-1,-2};//方向数组 

queue<pair<int,int> > q;

int n,m,x,y,f[10000][10000],vis[10000][10000];//vis是是否访问过的数组 

int main()
{
	cin>>n>>m>>x>>y;
	
	f[x][y] = 0;
	
	vis[x][y] = true;
	
	q.push({x,y});
	
	
	while(!q.empty()){
		
		int xx = q.front().first;
		
		int yy = q.front().second;
		
		q.pop();
		
		for(int i = 0;i<8;++i){
			int u = xx+dx[i],v = yy+dy[i];
			
			if(u<1||u>n||v<1||v>m||vis[u][v]) continue;
			
			vis[u][v] = true;
			
			q.push({u,v});
			
			f[u][v] = f[xx][yy]+1;
			
		}
	}
	
	
	
	for(int i=1;i<=n;++i)
		for(int j=1;j<=m;++j)
		{
			cout<<f[i][j]<<" \n"[j==m];
		}
	return 0;
}
2025/1/20 10:39
加载中...