首页 > 其他分享 >洛谷P1443:马的遍历--题解

洛谷P1443:马的遍历--题解

时间:2023-07-09 22:44:45浏览次数:36  
标签:洛谷 leq -- 题解 next int num frt path

写在前面

这是蒟蒻第一篇题解。作为一名没带脑子的初中生的第一篇题解,本题解必定存在诸多错误,给您带来的不便敬请谅解。对于不足之处与错误,还请多多包涵,并欢迎批评指正!
本题目来自于洛谷,网址https://www.luogu.com.cn/problem/P1443。
非营利性,侵权请联系删除。

题目详情

马的遍历

题目描述

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

输入格式

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

输出格式

一个 $n \times m$ 的矩阵,代表马到达某个点最少要走几步(不能到达则输出 $-1$)。

样例 #1

样例输入 #1

3 3 1 1

样例输出 #1

0    3    2    
3    -1   1    
2    1    4

提示

数据规模与约定

对于全部的测试点,保证 $1 \leq x \leq n \leq 400$,$1 \leq y \leq m \leq 400$。

题目解析

基本信息很长,但中心不多。有用的部分无非就是马每次可以到达8个点!

得到这个,我们很自然地就能想到用BFS(广度优先搜索)解决。
广搜的概念就不展示了,感兴趣的读者可以自己查一下 (话说如果不知道啥是广搜再看下去好像也没啥意义了)
怎么搜呢?
从能到达的8个点开始,每个点再向外延伸8个点,统计个数即可。

代码与讲解

开始准备工作:

int path_num[410][410];//存储各点路径数 
int x_next[8]={1,2,2,1,-1,-2,-2,-1};//表示“马”可一步到达的点的横坐标 
int y_next[8]={2,1,-1,-2,-2,-1,1,2};//表示“马”可一步到达的点的纵坐标
int n,m,x,y;//意义见题意 

用结构体存储坐标:

struct dot//表示坐标 
{
	int nx;//横坐标 
	int ny;//纵坐标 
}k,frt;//k表示待处理点,frt表示待处理点的上一个点 

搜索开始:

void bfs(int tx,int ty)//tx,ty分别表示“马”此时坐标 
{
	path_num[x][y]=0;//对“马”坐标初始化 
	k.nx=x;
	k.ny=y;
	queue<dot>q;
	q.push(k);//将“马”的坐标传入队列 
	while(!q.empty())//当前层级没有计算完 
	{
		frt=q.front();//一个一个计算 
		q.pop();//代表该元素已完成计算 
		for(int i=0;i<8;i++)//可直接到达的8个点 
		{
			int frt_next_x=frt.nx+x_next[i];//第i个点的横坐标 
			int frt_next_y=frt.ny+y_next[i];//第i个点的纵坐标 
			if(path_num[frt_next_x][frt_next_y]==-1&&frt_next_x>=1&&frt_next_x<=n&&frt_next_y>=1&&frt_next_y<=m)//该点没有超出棋盘边界且未计算过 
			{
				k.nx=frt_next_x;//记录新点横坐标 
				k.ny=frt_next_y;//记录新点纵坐标 	
				path_num[k.nx][k.ny]=path_num[frt.nx][frt.ny]+1;//新点路径数=原来点路径数+1 
		        q.push(k);//将新点存入队列,以进行下一次运算 
			}
		}		
	}
}

主函数:

int main()
{
	cin>>n>>m>>x>>y;
	memset(path_num,-1,sizeof(path_num));//默认均无法到达 
	bfs(x,y);//搜索 
	for(int i=1;i<=n;i++)
	{
		for(int j=1;j<=m;j++)
			cout<<left<<setw(5)<<path_num[i][j];//按格式输出 
		cout<<endl;
	}
}

全部代码

#include<bits/stdc++.h>
using namespace std;
int path_num[410][410];
int x_next[8]={1,2,2,1,-1,-2,-2,-1};
int y_next[8]={2,1,-1,-2,-2,-1,1,2};
int n,m,x,y;
struct dot
{
	int nx; 
	int ny;
}k,frt;
void bfs(int tx,int ty)
{
	path_num[x][y]=0;
	k.nx=x;
	k.ny=y;
	queue<dot>q;
	q.push(k);
	while(!q.empty())
	{
		frt=q.front();
		q.pop();
		for(int i=0;i<8;i++)
		{
			int frt_next_x=frt.nx+x_next[i];
			int frt_next_y=frt.ny+y_next[i];
			if(path_num[frt_next_x][frt_next_y]==-1&&frt_next_x>=1&&frt_next_x<=n&&frt_next_y>=1&&frt_next_y<=m)
			{
				k.nx=frt_next_x;
				k.ny=frt_next_y;
				path_num[k.nx][k.ny]=path_num[frt.nx][frt.ny]+1;
		        q.push(k);
			}
		}		
	}
}
int main()
{
	cin>>n>>m>>x>>y;
	memset(path_num,-1,sizeof(path_num));
	bfs(x,y);
	for(int i=1;i<=n;i++)
	{
		for(int j=1;j<=m;j++)
			cout<<left<<setw(5)<<path_num[i][j];
		cout<<endl;
	}
}

请注意:

变量有些多,有些变量纯粹为了省事 (少打字) ,一定注意区分!
一定要给数组path_num赋好初值
其实这道题稍微分析一下还是挺简单的>_<

时间复杂度分析

题目数据最大值是400,因此最多可能循环160000次
由于广搜是以空间换时间,因此时间复杂度相对较低,而空间复杂度则明显要高出不少
以下是洛谷运行结果:

写在最后

第一篇题解,质量不会高。
写了将近三个小时,还请体谅一下。
最后,再次声明:
本题解必定存在诸多错误,给您带来的不便敬请谅解。对于不足之处与错误,还请多多包涵,并欢迎批评指正!
本题目来自于洛谷,网址https://www.luogu.com.cn/problem/P1443。
非营利性,侵权请联系删除。

THE END~

标签:洛谷,leq,--,题解,next,int,num,frt,path
From: https://www.cnblogs.com/httony/p/17539603.html

相关文章

  • 7/9号随笔 落子无悔
    堕落了几天,但我并不想谈论那几天怎么样。因为都没有任何意义了。毕竟过去的都无法改变了。为什么学习。正如达尔文一样,变成更好的人。其实我喜欢很多东西,想买小米13u,哪怕找父母也会给我买,但是那花的是他们的钱,我想去自由自在,想去老君山,想去无人之地,看看山川河流,感受鸟语花香。......
  • Hash 学习笔记与总结
    Hash算法学习笔记与总结目录Hash字符串Hash信息学奥赛一本通AcWing模板模板题题目大意CODEHash表拉链法开放寻址法模板题题目大意CODEHash哈希算法是通过一个哈希函数H,将一种数据(包活字符串、较大的数等)转化为能够用变量表示或是直接就可作为数组下标的数,道过哈希函数......
  • watchEffect函数
    watch的套路是:既要指明监视的属性,也要指明监视的回调。watchEffect的套路是:不用指明监视哪个属性,监视的回调中用到哪个属性,那就监视哪个属性。watchEffect有点像computed:但computed注重的计算出来的值(回调函数的返回值),所以必须要写返回值。而watchEffect更注重的是......
  • 高等数学笔记
    第一章函数与极限第一节映射与函数映射函数......
  • [C/C++] 函数
    疑问1、函数结束后,函数栈释放的内容有哪些?2、通过函数修改形参的值怎么实现?值传递还是引用传递?基本类型、数组、结构体有什么区别?3、如果想通过函数对实参进行malloc,为什么必须用二级指针?函数栈空间在一个函数执行完毕后其所占用的内存空间(除了静态和全局变量)统统会被释放......
  • 学习博客链接
    Eva-J的博客:https://www.cnblogs.com/Eva-J/94007的博客:https://www.cnblogs.com/hswangnux/category/1274022.html隔壁老王的博客:https://www.cnblogs.com/wangfengming/隔壁老王MySQL博客:https://www.cnblogs.com/wangfengming/category/1118634.html隔壁老王MySQL正则表达......
  • WebSocket
    springboot项目中如何查看当前哪些客户端建立了webscoket连接如何在WebSocket请求连接时,带当前用户的id......
  • 1-MyBatisPlus 入门案例与简介
    1.入门案例MybatisPlus(简称MP)是基于MyBatis框架基础上开发的增强型工具,旨在简化开发、提供效率。开发方式基于MyBatis使用MyBatisPlus基于Spring使用MyBatisPlus基于SpringBoot使用MyBatisPlusSpringBoot整合MybatisPlus具体实现步骤为:创建数据库......
  • Go 语言 for-range 的两个坑,你踩过吗?
    坑一:迭代时协程引用索引和值先看看下面的例子,你知道最终输出的结果是什么吗?packagemainimport( "fmt" "time")funcmain(){ varm=[]int{1,3,5} fori,v:=rangem{ gofunc(){ fmt.Println(i,v) }() } time.Sleep(time.Second)}不知道的同学......
  • PPT中单个幻灯片添加不同编号
    情景:一个PPT中会有页码,也会有多个其它的编号,对于页码,好办,可以自动生成,但对于其他自定义的、只想在部分页面添加的编号,则需要写VBA脚本进行处理,使页码和自定义编号共存并真正实现编号在各个幻灯片中的自定义特征。采用如下VBA脚本实现自定义编号:SubAddCustomPageNumber()......