搜索(2):宽度优先搜索

目录

1.宽度优先搜索(BFS)

2.马的遍历(经典宽搜)

  2.1 建图

2.2 宽搜

2.3 完整代码

3.洛谷BFS

3.1 奇怪的电梯

3.2 Meteor Shower


1.宽度优先搜索(BFS)

     宽搜从根进入,向下逐层扩展,逐层访问

     宽搜是通过队列来实现的,用queue创建一个队列。宽搜的过程,通过队列来维护序列的状态空间,入队就排队等待,出队就将儿子们入队。

     宽搜的计算:出队后,入队前,结束后。

2.马的遍历(经典宽搜)

  2.1 建图

      对于最少步数的问题,我们建的图存的是到达该位置的最少步数,而队列的结构体元素存的是图中每个点的坐标,并进行判重

      dx[4],dy[4]存方向偏移量,因为走到每个格子,我们又有四个方向可以走,需要枚举每个方向

      格子就是点,格子到格子就是边

const int N=410;
int n,m,x,y;
int dx[8]={-1,-2,-2,-1,1,2,2,1};
int dy[8]={-2,-1,1,2,2,1,-1,-2};
struct node{int x,y;};
queue<node>q;//存点的坐标
int f[N][N],vis[N][N];//存步数和判重

2.2 宽搜

     从起点开始,先将起点入队并标记,之后开始宽搜,每次将队首元素出队,搜索它的周围元素,如果没有走过则进行标记,这是判重,因为之后再到这个位置的步数肯定比之前要多,所以我们标记之后就不会再搜索这个位置,然后将存步数的数组对该位置加1,之后将其压入队中,这是向外辐射扩散的。

void bfs(int x,int y)
{
  q.push({x,y});
  vis[x][y]=1;
  while(q.size())
 {
   auto u=q.front();
   q.pop();
   for(int i=0;i<8;i++)
   {
     int a=u.x+dx[i],b=u.y+dy[i];
     if(a<1||a>n||b<1||b>m||vis[a][b])continue;
     vis[a][b]=1;
     f[a][b]=f[u.x][u.y]+1;
     q.push({a,b});
   }
  }
}

2.3 完整代码

#include<bits/stdc++.h>
using namespace std;
const int N=410;
int n,m,x,y;
int dx[8]={-1,-2,-2,-1,1,2,2,1};
int dy[8]={-2,-1,1,2,2,1,-1,-2};
struct node{int x,y;};
queue<node>q;//存点的坐标
int f[N][N],vis[N][N];//存步数和判重
void bfs(int x,int y)
{
  q.push({x,y});
  vis[x][y]=1;
  while(q.size())
 {
   auto u=q.front();
   q.pop();
   for(int i=0;i<8;i++)
   {
     int a=u.x+dx[i],b=u.y+dy[i];
     if(a<1||a>n||b<1||b>m||vis[a][b])continue;
     vis[a][b]=1;
     f[a][b]=f[u.x][u.y]+1;
     q.push({a,b});
   }
  }
}
int main()
{
  cin>>n>>m>>x>>y;
  memset(f,-1,sizeof f);
  f[x][y]=0;
  bfs(x,y);
  for(int i=1;i<=n;i++)
     for(int j=1;j<=m;j++)
         printf("%-5d",f[i][j]);
     printf("\n");
  return 0;
}

3.洛谷BFS

    宽度优先搜索解决的就是最少步数问题,也可以用来解决方案数问题,但更倾向于用DFS。

3.1 奇怪的电梯

     这个题只有两个偏移方向,可以把这个电梯放倒,只有向左和向右两个方向。

#include<iostream>
#include<queue>
#include<cstring>
using namespace std;
const int N = 210;
int n, a, b;
queue<int>q;
int g[N], vis[N];//需要判重,因为一旦之前已经到达,那么之后再到达的步数一定大于之前到达的步数
int d[N];

void bfs(int a, int target)
{
    q.push(a);
    while (q.size())
    {
        auto u = q.front();
        if (a == target)return;
        q.pop();
        int nr = u + d[u], nl = u - d[u];
        if (nr >= 1 && nr <= n && !vis[nr]) g[nr] = g[u] + 1,vis[nr]=1,q.push(nr);
        if (nl >= 1 && nl <= n && !vis[nl]) g[nl] = g[u] + 1,vis[nl]=1,q.push(nl);
    }
}
int main()
{
    cin >> n >> a >> b;
    for (int i = 1; i <= n; i++)cin >> d[i];
    memset(g, -1, sizeof g);
    g[a] = 0;
    bfs(a, b);
    cout << g[b];
    return 0;
}

3.2 Meteor Shower

      这个题的难点在于如何避免贝茜在时刻t到达某个土地时这块土地还没有被撞击或烧焦,要想到达一个安全的格子,这个格子没有被流星撞击或烧焦,我们用数组来表示。

     还有某块土地会有多块陨石撞击或烧焦,我们选择最小的时刻。

#include<iostream>
#include<queue>
#include<cstring>
using namespace std;
const int N = 305;
struct node
{
	int x, y, time;
} p; 
int m, x, y, t, nx, ny, time1[N][N], vis[N][N]; 
int dx[4] = { 0,0,1,-1 }, dy[4] = { 1,-1,0,0 };
queue<node>q;
int main()
{
	cin >> m;
	memset(time1, -1, sizeof time1);
	for (int i = 1; i <= m; i++)
	{
		cin >> x >> y >> t;
		if (t < time1[x][y] || time1[x][y] == -1) //如果该时间小于之前被撞击的时间或者还没有被撞击,更新时间
			time1[x][y] = t;
		for (int i = 0; i < 4; i++)
		{
			nx = x + dx[i], ny = y + dy[i];
			if (nx >= 0 && ny >= 0 && (time1[nx][ny] == -1 || t < time1[nx][ny]))
				time1[nx][ny] = t;  //枚举焦土 
		}
	}
	q.push({ 0,0,0 }), vis[0][0] = 1;
	q.push(p);
	while (!q.empty())
	{
		p = q.front(); 
		q.pop();
		for (int i = 0; i < 4; i++)
		{
			nx = p.x + dx[i], ny = p.y + dy[i];
			if (nx >= 0 && ny >= 0 && vis[nx][ny] == 0 && (time1[nx][ny] == -1 || p.time + 1 < time1[nx][ny])) //没有流星到过或者贝茜到这个格子的时候流星还没有到达 
			{
				q.push({nx,ny,p.time+1});
				if (time1[nx][ny] == -1) //判断当前的格子是否安全 
				{
					cout << p.time+1 << endl;
					return 0;
				}
			}
		}
	}
	cout << -1 << endl; //到不了安全的格子就输出-1 
	return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/343361.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

DataStream API(输出算子)

源算子 源算子 转换算子 转换算子 输出算子 1.连接到外部系统 连接外部系统是计算机科学和信息技术领域中常见的一个任务&#xff0c;通常涉及到与外部数据源或服务进行交互。具体的方法和工具会根据不同的应用场景和需求而有所不同。以下是一些常见的连接外部系统的方法&…

什么是 Web3.0

什么是Web3.0 对于 Web3.0 的解释网上有很多&#xff0c;目前来说 Web3.0 是一个趋势&#xff0c;尚未有明确的定义。我们今天讨论下几个核心的点&#xff0c;就能很好的理解 Web3.0 要解决哪些问题 谁创造数据&#xff0c;这里的数据可以是一篇博客&#xff0c;一段视频&…

Linux的例行性工作(计划任务)

目录 一、单一执行的例行性任务--at&#xff08;一 次性&#xff09; 1、安装 2、启动服务 3、at命令详解 1&#xff09;格式 2&#xff09;参数 3&#xff09;时间格式 4、实例 二、循环执行的例行性任务-- crontab&#xff08;周期性&#xff09; 1、crontd服务 2…

【Go面试向】defer与time.sleep初探

【Go面试向】defer与time.sleep初探 大家好 我是寸铁&#x1f44a; 总结了一篇defer传参与time.sleep初探的文章✨ 喜欢的小伙伴可以点点关注 &#x1f49d; 请大家看下面这段代码&#xff0c;看运行结果会出现什么&#xff0c;为什么&#xff1f; 问题 demo package mainim…

基于SpringBoot Vue航空机票预订系统

大家好✌&#xff01;我是Dwzun。很高兴你能来阅读我&#xff0c;我会陆续更新Java后端、前端、数据库、项目案例等相关知识点总结&#xff0c;还为大家分享优质的实战项目&#xff0c;本人在Java项目开发领域有多年的经验&#xff0c;陆续会更新更多优质的Java实战项目&#x…

Qt-QFileDialog保存文件及获取带扩展名的文件名

正确用法 QFileDialog dialog(this, "Save File", QDir::currentPath(), "Text Files (.txt)"); dialog.setAcceptMode(QFileDialog::AcceptSave); dialog.setDefaultSuffix("txt"); // << if (!dialog.exec())return; QString fileName …

代码随想录算法训练营第28天 | 93.复原IP地址 + 78.子集 + 90.子集II

今日任务 93.复原IP地址 78.子集 90.子集II 93.复原IP地址 - Medium 题目链接&#xff1a;力扣&#xff08;LeetCode&#xff09;官网 - 全球极客挚爱的技术成长平台 有效 IP 地址 正好由四个整数&#xff08;每个整数位于 0 到 255 之间组成&#xff0c;且不能含有前导 0&a…

第一篇【传奇开心果系列】beeware的toga开发移动应用:轮盘抽奖移动应用

系列博文目录 beeware的toga开发移动应用示例系列博文目录一、项目目标二、开发传奇开心果轮盘抽奖安卓应用编程思路三、传奇开心果轮盘抽奖安卓应用示例代码四、补充抽奖逻辑实现五、开发传奇开心果轮盘抽奖苹果手机应用编程思路六、开发传奇开心果轮盘抽奖苹果手机应用示例代…

仓储管理系统——软件工程报告(总体设计)③

总体设计 一、需求规定 软件工程仓库存储管理系统的需求规定是确保系统能够满足用户期望、提高工作效率、确保数据安全性和系统可维护性的基石。其涵盖了功能性、性能、数据管理、用户界面和系统可维护性等多个方面。通过严格的验收标准&#xff0c;可以确保系统在实际应用中…

Linux: hardware: HP: DIMM

今天遇到一个问题是服务器上BIOS检查DIMM出现错误&#xff1a; 462-Uncorrectable Memory Error Threshold Exceeded(Processor 1, DIMM 14). The DIMM is mapped out and is currently not available. Action: Take corrective action for the failing DIMM. Re-map all DIMMs…

eNSP学习——配置通过STelnet登陆系统

目录 背景 实验内容 实验目的 实验步骤 实验拓扑 详细配置过程 基础配置 配置SSH server 配置SSH client 配置SFTP server 与client 背景 由于Telnet缺少安全的认证方式&#xff0c;而且传输过程采用的是TCP进行明文传输。单纯的提供Telnet服务容易招致主机IP地址欺骗、路…

机器学习之matplotlib学习

matplotlib库学习 matplotlib库的介绍折线图的绘制导入excel表数据绘制折线图 柱状图的绘制散点图的绘制扇形图的绘制总结 matplotlib库的介绍 折线图的绘制 绘制折线图使用plot函数进行绘制 第一个参数为x 横坐标&#xff0c;第二个参数为y纵坐标&#xff0c;第三个参数为线的…

linux的kali安装,换源,更新包

下载kali kali.org进入官网后点第二个 然后点第一个 解压kali 下载后获得.7z压缩包&#xff0c;建议移动到合适自己电脑的位置进行解压&#xff0c;我喜欢放在D盘 启动kali 双击进入解压出的文件夹&#xff0c;将唯一一个.vmx文件用vmware打开&#xff08;没装的自行提前装…

关于使用jdk8自带的日期类getDayOfWeek()的详细解释

问题引入 我们会发现getDayOfWeek()这个函数和其他自带函数不一样 直接写会报错 但是如果我们将他变成getDayOfWeek().getValue() 又能够正常运行,我们这次就来看看是为什么 解释 进入getDayOfWeek()源码查看 我们进入getDayOfWeek()的源码中查看 我们可以发现他给我们返回的…

Android 内存优化 内存泄漏

内存抖动 内存抖动是由于短时间内有大量对象进出新生区导致的&#xff0c;内存忽高忽低&#xff0c;有短时间内快速上升和下落的趋势&#xff0c;分析图呈锯齿状。 它伴随着频繁的GC&#xff0c;GC 会大量占用 UI 线程和CPU 资源&#xff0c;会导致APP 整体卡顿&#xff0c;甚…

Linux下用树莓派DS18B20温度传感器读取温度并上传至服务端

目录 一、DS18B20温度传感器 二、逻辑分析 三、实战操作 1、服务端 2、客户端 3、运行结果 一、DS18B20温度传感器 DS18B20是比较常用到的温度传感器&#xff0c;采用单总线控制。是美国DALLAS半导体公司继DS1820之后最新推出的一种改进型智能温度传感器。关于该温度传感…

Spring为啥不推荐使用@Autowired注解?

引言 使用IDEA开发时&#xff0c;同组小伙伴都喜欢用Autowired注入&#xff0c;代码一片warning&#xff0c;看着很不舒服&#xff0c;Autowired作为Spring的亲儿子&#xff0c;为啥在IDEA中提示了一个警告&#xff1a;Field injection is not recommended 想搞清楚这个问题之…

Unity3d C#实现三维场景中图标根据相机距离动态缩放功能

前言 如题的需求&#xff0c;其实可以通过使用UI替代场景中的图标来实现&#xff0c;不过这样UI的处理稍微麻烦&#xff0c;而且需要在图标上添加粒子特效使用SpriteRender更方便快捷。这里就根据相机离图标的位置来计算图标的缩放大小即可。这样基本保持了图标的大小&#xf…

【51单片机】IO 扩展(串转并)--74HC595

0、前言 参考&#xff1a; 普中 51 单片机开发攻略 第12章 【51单片机入门教程-2020版 程序全程纯手打 从零开始入门】 https://www.bilibili.com/video/BV1Mb411e7re/?p21&share_sourcecopy_web&vd_source77e36f24add8dc77c362748ffb980148 nop()是什么语句&#…

LLM:RoPE - 开源代码中的实现 (下)

本文着重学习一下开源代码中关于RoPE的实现:ChatGLM-6B、ChatGLM2-6B、LLAMA 回顾一下RoPE位置编码: 1:对于 token 序列中的每个词嵌入向量,首先计算其对应的 query 和 key 向量 2:然后对每个 token 位置都计算对应的旋转位置编码 3:接着对每个 token 位置的 query 和 …
最新文章