BFS宽度优先搜索例题(蓝桥杯)——逃跑的牛

问题描述:

  农夫John的一头牛逃跑了,他想要将逃跑的牛找回来。现假设农夫John和牛的位置都在一条直线上,农夫John的初始位置为N(0≤N≤100,000),牛的初始位置为K(0≤K≤100,000)。农夫John有两种移动方式:行走和传送。
  行走:农夫John可以从当前位置X移动到X-1或X+1,花费时间1分钟。
  传送:农夫John可以从当前位置X传送到2×X,花费时间1分钟。
  现假设牛逃跑后的位置一直保持不变,请编写一个程序,计算农夫John找到牛的最短时间。

输入格式:输入N和K(中间用一个空格间隔)。

输出格式:输出最短的寻找时间,单位分钟。

方法:

        宽度优先搜索算法(又称广度优先搜索)是最简便的图的搜索算法之一,这一算法也是很多重要的图的算法的原型。Dijkstra单源最短路径算法和Prim最小生成树算法都采用了和宽度优先搜索类似的思想。其别名又叫BFS,属于一种盲目搜寻法,目的是系统地展开并检查图中的所有节点,以找寻结果。换句话说,它并不考虑结果的可能位置,彻底地搜索整张图,直到找到结果为止。

分析:

首先,每一步(节点)都有两个信息要素:当前距离和时间,故声明一个结构体

struct S
{
    int time;
    int add;
}

其次,bfs多使用队列(queue)进行各个分支的遍历,队列:先进先出

queue<S> q;

首先第一个节点是:

S s0={0,n}; //cin>>n>>k;

bfs的关键思路是遍历队列中的每个节点,进行i(i=3)次操作,生成i个新的节点,继续放在队列中。(每次操作需要pop当前遍历到的节点,观察是否达到目标,如果有,跳出当前操作,没有就做对应的操作,生成对应三个操作后的新节点放入队列中)

        因为每一层操作都是time+1,整个搜索过程是按照一层一层搜索的,所以只要当前没有结束搜索,那么此时这个一定是最快的方法(之一)直接退出搜索就好了:输出最优解时间。

while(!q.empty()) //队列不空
{
    0.取出队列首元素 S s=q.front();
    1.判断是否达到目标?跳出搜索:进行三种操作并生成对应节点,放入队列
    2.三个操作
   (1) (s.add+1) 创造新节点s1={s.time+1,a.add+1},放入队列
   (2) (s.add-1) 创造新节点s1={s.time+1,a.add-1},放入队列
   (3) (s.add*2) 创造新节点s1={s.time+1,a.add*2},放入队列
}

优化操作:进行剪枝

剪枝情况1:创建一个flag数组,登记当前add情况有没有在此之前就搜索过(如果之前有,那么当前搜索状况一定不是最优的,没必要按照当前这条路继续搜索下去)——搜索过就不搜索了

剪枝情况2:如果当前add<=0 则不需要进行add-1和add*2的操作——不进行无意义的操作

剪枝情况3:如果add>k 则不进行add+1和add*2的操作——同上

特殊情况:牛在农夫前面(n>k),只能进行操作(2),直接输出结果即可(但是由于剪枝的存在,这样的特殊情况特殊处理不会带来特别大的优化)

while(!q.empty()) //队列不空
{
    0.取出队列首元素 S s=q.front();
    1.判断是否搜索过(flag)?如果没有:
        {
            2.判断是否达到目标?如果有:跳出搜索,输出最短时间。否则:
            {
                3.判断是否add<=0?只进行操作(1)
                  判断是否add>k?只进行操作(2)
                  否则:进行三个操作
            }
            4.将flag置为1(已搜索)
        }
}

代码实现: 

#include<iostream>
#include<queue>
using namespace std;

struct S{
    int time;//所用时间
    int add;//当前位置
};


int flag[200000] = {0};//标识对应位置是否求过
queue<S> q;//队列存储当前操作节点
int k;//全局对照量(目标距离k)

void bfs()
{
    while(!q.empty())//队列不为空继续搜索
    {
        S s = q.front();//头结点
        cout<<"现在遍历节点为:add="<<s.add<<" time="<<s.time<<endl;
        q.pop();//删除头结点
        if(flag[s.add]==0)//(剪枝1)
        {
            if(s.add==k)//农夫的位置和牛的位置一样,抓到了
            {
                cout << "农夫的位置和牛的位置相同(抓到牛了) 花费时间:"<<s.time << endl;
                break;//跳出while循环
            }
            //三个操作
            S next;//创建新节点
            next.time = s.time + 1;//所有操作都是time+1

            if(s.add>k)//(剪枝2)
            {
                next.add = s.add - 1;
                q.push(next);
                cout<<"新节点入队: add="<<next.add<<" time="<<next.time<<endl;
            }
            else if(s.add<=0)
            {
                next.add = s.add + 1;
                q.push(next);
                cout<<"新节点入队: add="<<next.add<<" time="<<next.time<<endl;
            }
            else
            {
                next.add = s.add - 1;
                q.push(next);
                cout<<"新节点入队: add="<<next.add<<" time="<<next.time<<endl;
                next.add = s.add + 1;
                q.push(next);
                cout<<"新节点入队: add="<<next.add<<" time="<<next.time<<endl;
                next.add = s.add * 2;
                q.push(next);
                cout<<"新节点入队: add="<<next.add<<" time="<<next.time<<endl;
            }
            flag[s.add] = 1;//标识这个位置计算过了
        }
    }

}

int main()
{
    int n;//农夫的位置
    cin >> n >> k;
    S s={0,n};
    q.push(s);
    bfs();//进行宽度优先搜索
    return 0;
}

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

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

相关文章

人社大赛算法赛题解题思路分享+季军+三马一曹团队

团队成员介绍: 梅鵾 上海交通大学 众安科技 算法工程师 吴栋梁 复旦大学 众安科技 算法工程师 李玉娇 复旦大学 众安科技 算法工程师 一、赛题背景分析及理解 本赛题提供了部分地区2016年度的医疗保险就医结…

改进YOLOv8注意力系列七:结合空间关系增强注意力SGE、SKAttention动态尺度注意力、TripletAttention

改进YOLOv8注意力系列七:结合空间关系增强注意力SGE、SKAttention动态尺度注意力、全局上下文信息注意力Triplet Attention 代码Spatial Group Enhance (SGE)SKAttention动态尺度注意力全局上下文信息注意力Triplet Attention(无参)加入方法各种yaml加入结构本文提供了改进 Y…

openGauss 5.0 单点企业版部署_Centos7_x86(上)

背景 通过openGauss提供的脚本安装时&#xff0c;只允许在单台物理机部署一个数据库系统。如果您需要在单台物理机部署多个数据库系统&#xff0c;建议您通过命令行安装&#xff0c;不需要通过openGauss提供的安装脚本执行安装。 本文档环境&#xff1a;CentOS7.9 x86_64 4G1…

IDEA import时不使用*

在使用 IDEA 进行开发时&#xff0c;会经常使用到 import 关键字导入所需的类。 IDEA 默认设置是同包类是超过 5 个或者静态导入超过 3 个变成 import xxx.*。 但 import xxx.* 的形式会造成一些用不到的类被引入&#xff0c;导致资源浪费&#xff0c;最好还是不使用这种方式…

雷达学习之多普勒频率

一、多普勒频率如何产生&#xff1f; 雷达的原理是发射一些无线电脉冲来探测目标&#xff0c;并通过回波的延时来计算目标与雷达的距离&#xff0c;但当目标为运动物体时&#xff0c;在回波向目标传输的同时&#xff0c;目标也会远离或接近回波&#xff0c;所以会导致回波信号…

【git】checkout origin/xxx 出现 detached HEAD问题

git 检出远程分支出现Head分离的是什么原因导致的呢&#xff1f;&#xff1f; 因为Head指向了origin的一个commit, 但是这个origin分支你的本地又没有&#xff0c;也就是说你本地没有追踪这个分支&#xff0c;那就要track一下 git checkout -h 看一下有没有追踪的命令 果不其…

【golang】动态生成微信小程序二维码实战下:golang 生成 小程序二维码图片 并通过s3协议上传到对象存储桶 | 腾讯云 cos

项目背景 在自研的系统&#xff0c;需要实现类似草料二维码的功能 将我们自己的小程序&#xff0c;通过代码生成相想要的小程序二维码 代码已经上传到 Github 需要的朋友可以自取 https://github.com/ctra-wang/wechat-mini-qrcode 一、生成Qrcode并提交到对象存储 通过源生A…

前端:自制年历

详细思路可以看我的另一篇文章《前端&#xff1a;自制月历》&#xff0c;基本思路一致&#xff0c;只是元素布局略有差异 ①获取起始位startnew Date(moment().format(yyyy-01-01)).getDay() ②获取总的格子数numMath.ceil(365/7)*7,这里用365或者366计算结果都是一样的371 …

数据库中了勒索病毒怎么办?(数据库恢复的终极大招DUL)

数据库如何预防勒索病毒 接上文&#xff0c;如果数据库中了勒索病毒&#xff0c;并且备份也同样被攻陷&#xff0c;那该怎么办&#xff1f;以最为常见的Lockbit3.0为例&#xff0c;LockBit采用先进的加密算法&#xff0c;通常是对称密钥加密和非对称密钥加密的组合。这使得被感…

适合虚拟主持人活动的全身动作捕捉设备:VDSuit Full

在虚拟主持人领域&#xff0c;全身动作捕捉设备一直以其逼真的效果和生动的表现力备受瞩目。相比光学全身动作捕捉设备&#xff0c;惯性全身动作捕捉设备更适合应用在企业品牌虚拟主持人发布会、虚拟主持人直播等活动场合。 广州虚拟动力全身动作捕捉设备VDSuit Full&#xff0…

OSCP靶场--Nagoya

OSCP靶场–Nagoya 考点 1.nmap扫描 ## ┌──(root㉿kali)-[~/Desktop] └─# nmap 192.168.214.21 -sV -sC -Pn --min-rate 2500 -p- Starting Nmap 7.92 ( https://nmap.org ) at 2024-04-02 08:52 EDT Nmap scan report for 192.168.214.21 Host is up (0.38s latency).…

colmap安装问题汇总

问题目录 问题0、没有root权限怎么安装colmap&#xff1f; 问题1、ERROR: SiftGPU not fully supported/Could not connect to any X display 问题2、Cannot specify include directories for imported target "freeimage::FreeImage". 问题3、could not find ZL4 问…

鸿蒙ArkUI开发学习:【渲染控制语法】

ArkUI开发框架是一套构建 HarmonyOS / OpenHarmony 应用界面的声明式UI开发框架&#xff0c;它支持程序使用 if/else 条件渲染&#xff0c; ForEach 循环渲染以及 LazyForEach 懒加载渲染。本节笔者介绍一下这三种渲染方式的使用。 if/else条件渲染 使用 if/else 进行条件渲染…

AI大模型的10大趋势预判!

大模型发展竞争愈发激烈。全球瞩目的文生视频Sora、谷歌Gemini 1.5、Meta的V-JEPA以及超越GPT4的Claude3相继发布。Open AI的GPT5也即将问世。奥特曼不仅自研芯片&#xff0c;还投资可控核聚变公司&#xff0c;以算力和能源为未来储备关键资源。 在算力紧平衡和数据资源荒的背…

俄罗斯留学有哪些世界一流的名校呢,柯桥留学俄语培训

有哪些世界一流的名校呢 ☢ 理工类院校 俄罗斯是科教大国&#xff0c;高等教育水平位于世界前列&#xff0c;拥有许多国际著名大学。众多世界知名大学拥有很多独具特色的优势专业&#xff0c;其中理工类大学得天独厚的专业性也是被世界所认可的。凭着其高水准的教育&#xff…

gitee和idea集成

1 集成插件 2 配置账号密码 3 直接将项目传到仓库 4直接从gitee下载项目

yolov5交互式界面 通用界面-yolo-pyqt-gui(通用界面制作+代码-V5.0-6.0版本)

"YOLOv5交互式界面 - 通用界面-YOLO-PyQt-GUI" 它为YOLOv5的目标检测模型提供了一个用户友好的图形化操作界面。该项目通常基于Python的PyQt库构建&#xff0c;用于封装YOLOv5的功能&#xff0c;并将其转化为可视化工具&#xff0c;使得非专业开发人员也能便捷地使用…

超越接口:探索Dubbo的泛化调用机制

欢迎来到我的博客&#xff0c;代码的世界里&#xff0c;每一行都是一个故事 超越接口&#xff1a;探索Dubbo的泛化调用机制 前言泛化调用的概念Dubbo 中泛化调用的工作原理泛化实现动态RPC泛化调用的高级用法参数和返回值处理异常处理和错误处理策略 controller实践 前言 在现…

为什么 MySQL 采用 B+ 树作为索引?

资料来源 : 小林coding 小林官方网站 : 小林coding (xiaolincoding.com) 「为什么 MySQL 采用 B 树作为索引&#xff1f;」这句话&#xff0c;是不是在面试时经常出现。 要解释这个问题&#xff0c;其实不单单要从数据结构的角度出发&#xff0c;还要考虑磁盘 I/O 操作次数&am…

C语言-函数指针-快速排序算法(书籍示例-入门)

概述 使用C语言&#xff0c;实现结构体多元素&#xff0c;排序算法&#xff08;冒泡排序&#xff09;&#xff0c;这里使用示例&#xff1a;书籍示例讲解 函数简介 函数声明 void qsort(void *base, size_t nitems, size_t size, int (*compar)(const void *, const void*)) 参…