当前位置: 首页 > news >正文

算法day5 bfs搜索

一  马的遍历

首先我们之前学习bfs的时候是以走迷宫来讲述的,但是那个是一步一步走的,如果我们不是一步一步走的,而是有规律性,但是又不是一步一步走的该怎么办?
首先我们分析一下走日子的话不就是8个方向吗
然后我们只需要在向量数组里面写8个方向的参数就好了,但是怎么写呢?

我们来开这个图,每一个绿色的点就是它所对应的单位向量的坐标,所以我们就可以写出这个数组

int dx[]={2,  1,-1,-2,-2,-1,1,2};
int dy[]={-1,-2,-2,-1, 1, 2,2,1};

 这个就是对应每一个点的向量坐标
后面呢就是跟走迷宫一样的操作了

#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;

typedef pair<int,int> PII;

const int N = 410;
int n,m;
int dist[N][N];
PII q[N*N];
int hh =0,tt=-1;

int dx[]={2,  1,-1,-2,-2,-1,1,2};
int dy[]={-1,-2,-2,-1, 1, 2,2,1};

void bfs(int x,int y){
    dist[x][y]=0;
    q[++tt]={x,y};
    
    while(hh<=tt){
        auto t = q[hh++];
        for(int i=0;i<8;i++){
            int a = t.first + dx[i];
            int b = t.second + dy[i];
            
            if(a>n||a<1||b>m||b<1) continue;
            if(dist[a][b]>=0) continue;
            
            dist[a][b]=dist[t.first][t.second]+1;
            q[++tt]={a,b};
        }
    }
}

int main(){
    scanf("%d %d",&n,&m);
    int x,y;
    scanf("%d %d",&x,&y);
    memset(dist,-1,sizeof(dist));
    bfs(x,y);
    
    for(int i=1;i<=n;i++){
        for(int j=1;j<=m;j++){
            printf("%-5d",dist[i][j]);
        }
        printf("\n");
    }
    
    return 0;
}

这里比较难以理解的就是这个队列了
当然你也可以用stl库里面的队列,但是那个运行起来相对较为缓慢,我们为了提高效率就手写了一个队列
我们来分析一下这个队列是怎么写的

PII q[N*N];
int hh =0,tt=-1;

首先这个队列就是先进先出嘛
然后我就定义了一个数组,这个数组的类型是二元组
然后这个hh是这个队列的头部,这个tt是队列的尾部
为什么设置为-1呢?因为当有一个元素插入进来之后不就是tt变成了0了么
出去是hh动,进来是tt动
 然后我们就是写队列

    dist[x][y]=0;
    q[++tt]={x,y};
    
    while(hh<=tt){
        auto t = q[hh++];
        for(int i=0;i<8;i++){
            int a = t.first + dx[i];
            int b = t.second + dy[i];
            
            if(a>n||a<1||b>m||b<1) continue;
            if(dist[a][b]>=0) continue;
            
            dist[a][b]=dist[t.first][t.second]+1;
            q[++tt]={a,b};
        }
    }

 首先这个++tt就是push的操作,表示把一个元素放入
还记得前缀表达式和后缀表达h式吧,这就是,先++然后把元素进行放入
这个hh<=tt就是表示这个队列不可以为空
然后后面的hh++就是先把这个元素取出,然后再pop这个hh到后面去了,就是pop操作了
然后下面就是在结尾处加一个元素
 

 二  血色先锋队

 我们来看这个题目,这个题目就是多源bfs了,就是多个地方同时走,但是这个也不影响我们解题,因为我们队列是先进先出的,然后就是上一个感染源出来之后,就是下一个感染源,如果这个时候有两个感染源的话就是下一步就是第一个感染源的分支先出了,这样我们就做到了每个感染源都有考虑到的方法

#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;

typedef pair<int,int> PII;

const int N=510;
int n,m;
int dist[N][N];
PII q[N*N];
int hh=0,tt=-1;

int dx[]={-1,0,1, 0};
int dy[]={ 0,1,0,-1};

void bfs(){
    while(hh<=tt){
       auto t = q[hh++];
       for(int i=0;i<4;i++){
           int a = t.first+ dx[i];
           int b = t.second+dy[i];
           
           if(a<1||a>n||b<1||b>m) continue;
           if(dist[a][b]>=0)continue;
           
           dist[a][b]=dist[t.first][t.second]+1;
           q[++tt]={a,b};
       }
    }
}

int main(){
    int a,b;
    scanf("%d %d",&n,&m);
    scanf("%d %d",&a,&b);
    
    memset(dist, -1 ,sizeof(dist));
    while(a--){
        int x,y;
        scanf("%d %d",&x,&y);
        dist[x][y]=0;
        q[++tt]={x,y};
    }
    
    bfs();
    
    while(b--){
    int x,y;
    scanf("%d %d",&x,&y);
    printf("%d\n",dist[x][y]);
    }
    
    return 0;
}

这个是代码,我是先输入感染源,判断完之后再输入首领,这样就可以直接打印了


总结 

其实bfs都是有一个通用的模式就是
要一个向量坐标
而且要有条件判断,再每次走对应方向的时候
然后要有一个状态数组也可以叫做足迹数组,这样我们就可以每次去加自己的足迹值,如果题目要求要这个足迹值也可以打印出,又或者可以作为条件走没有走过的值
还要有一个边界条件,防止走出去了
最后就是队列了,我们一开始一定要放一个元素,然后取走它并且弹出,如果下一个值符合条件,我们就又可以下一个值放进去,然后就可以对这个子值进行判断

所以就是队列,足迹值,向量坐标,条件,continue的使用

相关文章:

  • 图像分类项目1:基于卷积神经网络的动物图像分类
  • JavaEE基础之- 过滤器和监听器Filter and Listener
  • 迷你世界脚本状态接口:Buff
  • 在.net中,async/await的理解
  • 【实战篇】【深度解析DeepSeek:从机器学习到深度学习的全场景落地指南】
  • 通往 AI 之路:Python 机器学习入门-面向对象编程
  • 数据库拓展操作
  • 阿里云 Qwen2.5-Max:超大规模 MoE 模型架构和性能评估
  • 大白话面试遇难题,应对策略是什么?
  • 微信小程序开发学习笔记
  • 知识库技术选型:主流Embedding模型特性对比
  • 阿里云ECS Ubuntu PPTP VPN无法访问以太网
  • 使用SPI总线与外部传感器通信,使用ECU抽象
  • 【Git】Ubuntu 安装 Git Large File Storage(LFS)以及使用 Git LFS 下载
  • 上位机知识篇---Linux\Windows操作系统下获取逻辑处理器数
  • Grok 3 AI 角色扮演提示词 化身顶级设计师
  • 【AD】4-2 利用IPC封装创建向导快速创建PCB封装-SOP8
  • 进程间通信(IPC)与匿名管道
  • Java容器异常分析与恢复实战指南
  • 20250302小米13ultra删除照片后没有在回收站
  • 青岛网站推广/网络营销课程总结与心得体会
  • 2024年新闻热点事件摘抄/搜索引擎优化方案
  • 在线教育网站开发时长/百度关键词搜索广告的优缺点
  • 医院电子网站建设/查域名备案信息查询
  • 成都的网站/交易链接
  • 常州市网站建设/成人速成班有哪些专业