蓝桥杯备赛_python_BFS搜索算法_刷题学习笔记

1 bfs广度优先搜索

1.1 是什么

1.2怎么实现

2案例学习

2.1.走迷宫

 2.2.P1443 马的遍历

2.3. 九宫重排(看答案学的,实在写不来)

 2.4.青蛙跳杯子(学完九宫重排再做bingo)

2.5. 长草

 3.总结


1 bfs广度优先搜索

【Python搜索算法】广度优先搜索(BFS)算法原理详解与应用,示例+代码_广度优先算法的路径搜索代码-CSDN博客

1.1 是什么

        看了其他大佬的分享之后,我理解的广度优先搜索是一种图遍历的算法,简单来说是他的访问规则是一层一层的访问,先访问距离节点近的数据,再逐层拓展访问远的数据。与广度优先搜索密切相关的数据类型叫做队列。队列我们可以理解为是日常生活中排队所形成的队形,先进先出是队列最大的特点。

1.2怎么实现

BFS算法的步骤如下:

  1. 初始化:选择一个起始节点,将其标记为已访问,并将其放入队列中(作为起始节点)。
  2. 进入循环:重复以下步骤,直到队列为空。 a. 从队列中取出一个节点。 b. 访问该节点。 c. 将所有未访问的相邻节点加入队列。 d. 标记已访问的节点,以避免重复访问。
  3. 结束循环:当队列为空时,表示已经遍历完整个图。

算法原理:

        BFS的工作原理是通过队列数据结构来管理待访问的节点。它从起始节点开始,然后逐一访问该节点的相邻节点,并将它们加入队列。然后,它从队列中取出下一个节点进行访问,以此类推。这确保了节点按照它们的距离从起始节点逐层遍历,因此BFS可以用于查找最短路径。

        BFS是一个宽度优先的搜索,它在查找最短路径等问题中非常有用。它不会陷入深度过深的路径,因为它会优先探索距离起始节点更近的节点。

总结:广度优先搜索一般来说都会有一个队列去存储节点,同时也会有一个数组去记录访问的状态。 

2案例学习

2.1.走迷宫

输入:

5 5 
1 0 1 1 0
1 1 0 1 1 
0 1 0 1 1
1 1 1 1 1
1 0 0 0 1
1 1 5 5 

输出:

8

         说明一下这道题的思路,这道题非常直观体现了BFS,并且是最基本的BFS。那代码的思路是怎么样的呢?我们来捋一下。

        一开始所说的队列其实就是列表,只是用到了队列的特点,也就是说队列其实就是类似于列表,只是这个算法的思路用到了队列的特点,一开始我想得太复杂了,总以为队列是一个很高级的容器,其实简单理解就是列表。

        那根据BFS的算法思路:

  1. 初始化:将迷宫的起点作为起始节点        queue=[(x1-1,y1-1,step)]
  2. 进入循环:循环终止的条件是什么,当列表为空就终止了       while queue:                    怎么取出列表的第一个元素,这个时候就是队列的特点,先进先出,怎么体现在列表中,进去就是存入,出来就是删除      x,y,step=queue.pop(0)                                          这里页需要注意走迷宫有上下左右四个方向对应的就是坐标的变化,这也是我对子节点的一个理解

         同时已经访问过的点也要做好标记

        我当时还有一个特别想不懂的,哈哈哈哈哈哈,想起来感觉自己特别蠢哈哈哈哈哈。

        怎么着,我想着每一个节点都有四个子节点,那意味着线路会不一样,怎么就知道那一个的step是最小的,结果我看到那个判断的出口就一下子大悟了,最短路径嘛,那早点满足出口条件的不就是最短路径嘛

n, m = map(int,input().split())
data = []
d = [[1,0],[-1,0],[0,1],[0,-1]]
for i in range(n):
    l = list(map(int,input().split()))
    data.append(l)
x1, y1, x2, y2 = map(int,input().split())
def bfs(x1,y1,step):
    queue=[(x1-1,y1-1,step)]
    while queue:
        x,y,step=queue.pop(0)
        if x==x2-1 and y==y2-1:
            return step
        for xx,yy in d:
            dx = x+xx
            dy = y+yy
            if 0<= dx <n and 0<= dy <m and data[dx][dy] :
                data[dx][dy]=0
                queue.append((dx,dy,step+1))
    return -1
print(bfs(x1,y1,0))
 2.2.P1443 马的遍历

做好久了但是还是没有完全通过,怎么办可以帮忙看看嘛 

n, m, x, y= map(int,input().split())
d = [[-1,2],[-2,1],[-2,-1],[-1,-2],[1,2],[2,1],[2,-1],[1,-2]]
data = []
result = [[0 for _ in range(m)]for _ in range(n)]
for i in range(1,n+1):
    for j in range(1,m+1):
        data.append([i,j])
from collections import deque
def bfs(x,y,a,b,step,visit):
    queue = deque([(x,y,step)])
    while len(queue) != 0:
        x1, y1, step = queue.popleft()
        if x1 == a and y1 == b:
            return step
        for xx,yy in d:
            dx = x1+xx
            dy = y1+yy
            if dx < 1 or dx > n or dy < 1 or dy > m:
                continue
            if visit[dx][dy] == 0:
                visit[dx][dy] = 1
                queue.append((dx, dy, step + 1))
    return -1


for i,j in data:
    visit = [[0 for _ in range(m + 1)] for _ in range(n + 1)]
    visit[x][y] = 1
    ans = bfs(x,y,i,j,0,visit)
    result[i-1][j-1] = ans
for i in result:
    for j in i:
        print(j,end='\t')
    print('\n',end='')

2.3. 九宫重排(看答案学的,实在写不来)

6.九宫重排 - 蓝桥云课 (lanqiao.cn)

        我当时自己做的时候就在纠结到底是移动格子还是移动数字,很显然,如果要移动数字那每个数字都需要移动,但是移动格子的话我们只需要对这个格子进行操作就可以了。所以移动格子是最佳方案。

         以下是我自己写的错误代码,真的是错的离谱,纪念一下我稀里糊涂的脑子

start = input()
end = input()

map1 = [[0 for _ in range(3)] for _ in range(3)]
map2 = [[0 for _ in range(3)] for _ in range(3)]
k1, k2 = 0, 0
for i in range(3):
    for j in range(3):
        map1[i][j] = start[k1]
        if start[k1] == '.':
            a, b = i, j
        k1 += 1
for i in range(3):
    for j in range(3):
        map2[i][j] = end[k2]
        k2 += 1

d = [[1,0],[-1,0],[0,1],[0,-1]]

def bfs(a,b,step):
    global map1
    visit = [[0 for _ in range(3)] for _ in range(3)]
    queue = [(a,b,step)]
    visit[a][b] = 1
    while queue:
        x, y, step = queue.pop(0)
        if map1 == map2:
            return step
        for xx,yy in d:
            dx = x+xx
            dy = y+yy
            if dx<0 or dx>2 or dy<0 or dy>2:
                continue
            if visit[dx][dy] == 0:
                visit[dx][dy] = 1
                map1[x][y],map1[dx][dy] = map1[dx][dy],map1[x][y]
                queue.append((dx,dy,step+1))
    return -1
print(bfs(a,b,0))

         别人大佬的代码代码写的真好

蓝桥杯:九宫格重排【BFS】【Python】_重排九宫问题bfs-CSDN博客

        当然我在别人的代码上加上了一些修改以及注释,主要是得自己看得懂

        我也反思了一下自己写的代码思路和别人的,我在一维和二维的变换上处理的十分混乱,导致自己都不知道到底是个什么事儿,因为我也知道是去移动格子,然后交换,但是我就很混乱。当然我的思路还有一些错误。

        别人的代码思路这一点我真是没想到,就是用字典的键值对去存储每一次移动格子后所形成的新字符串的步数,一旦相等了就可以直接返回。

start = input()
end = input()

from collections import deque
def bfs():
    # 创建容器并初始化
    # 创建字典存储每次变换字符串的步数
    dic = {}
    dic[start] = 0
    # 创建队列
    queue = deque()
    queue.append(start)
    d = [[1, 0], [-1, 0], [0, 1], [0, -1]]
    # 进入循环
    while queue:
        now_start = list(queue.popleft())
        # 循环结束出口
        if "".join(now_start) == end:
            return dic["".join(now_start)]
        point = now_start.index('.')
        # 一维的下标转换为二维下标:
        # 转换公式:x = index//二维数组的宽度    y = index%二维数组的宽度
        x = point // 3
        y = point % 3

        step = dic["".join(now_start)]

        for xx,yy in d:
            dx = x+xx
            dy = y+yy
            if dx>=0 and dx<3 and dy>=0 and dy<3:
                new_start = now_start.copy()
                # 二维转一维
                # 转换公式:index = x*二维数组的宽度 + y
                new_start[point],new_start[dx*3+dy] = new_start[dx*3+dy],new_start[point]
                if "".join(new_start) not in dic.keys():
                    # dic.setdefault("".join(new_start),step+1)
                    dic["".join(new_start)] = step+1
                    queue.append("".join(new_start))
    return -1

print(bfs())

 

 知识点笔记:

 2.4.青蛙跳杯子(学完九宫重排再做bingo)

1.青蛙跳杯子 - 蓝桥云课 (lanqiao.cn)

        那学完九宫重排之后写这道题就非常简单了,并且这道题还是一维的,不用转换,其他思路跟九宫重排一模一样。

        题目中所说的三种动作,虽然说是青蛙的跳动,但是把当作杯子的跳动去处理就会简单很多,总之学完九宫重排之后这道题就是很简单了。

start = input()
end = input()

from collections import deque
def bfs():
    d = [1, -1, 2, -2, 3, -3]
    queue = deque()
    queue.append(start)
    dic = {}
    dic[start] = 0

    while queue:
        now_start = list(queue.popleft())
        point = now_start.index('*')

        step = dic["".join(now_start)]

        if "".join(now_start) == end:
            return dic["".join(now_start)]

        for xx in d:
            dx = point+xx
            new_start = now_start.copy()
            if dx in range(0, len(start)):
                new_start[point], new_start[dx] = new_start[dx], new_start[point]
                if "".join(new_start) not in dic.keys():
                    dic["".join(new_start)] = step+1
                    queue.append("".join(new_start))
    return -1

print(bfs())

2.5. 长草

0长草 - 蓝桥云课 (lanqiao.cn)

        这道题一开始的思路是想到了非连通图的遍历,然后我就是这么一个思路,先找到一个初始化的点先进行广度优先搜索,只进行K层的搜索,但是我一直都无法找到怎样去把握让搜索测层数是我想要的,不知道这个怎么解决,在这里遇到了大问题,然后再遍历我的地图看看还有没有另外的点需要搜索的。所以这个思路就需要两个数组,一个是队列,一个是记录我的访问状态,但是我并没有解决。

        然后就换了一个思路,将节点先依次入队,再对每一个节点进行广度优先搜索,这个就比较好控制,多少层那我就调用多少次的bfs。这里有一个点就在于我的while循环的出口是与队列的长度有关(或者是说节点的个数),因为队列只有把所有的节点都遍历完成之后才算。

        总之这道题也是一道与之前有着一点区别的,也可以算作是遍历非连通图的一种方法。

n, m = map(int,input().split())
maps = []
for i in range(n):
    l = list(input())
    maps.append(l)
k = int(input())

from collections import deque
queue = deque()
for i in range(n):
    for j in range(m):
        if maps[i][j] == 'g':
            queue.append((i,j))

d = [[1,0],[-1,0],[0,1],[0,-1]]
def bfs():
    ans = len(queue)
    while ans:
        x1, y1 = queue.popleft()
        for xx,yy in d:
            dx = x1+xx
            dy = y1+yy
            # if dx<0 or dx>=n or dy<0 or dy>=m:
            #     continu
            if 0<=dx<n and 0<=dy<m and maps[dx][dy] == '.':
                maps[dx][dy] = 'g'
                queue.append((dx,dy))
        ans -= 1

for i in range(k):
    bfs()
for i in maps:
    print(''.join(i))

 

 3.总结

学习还在继续,持续学习加油!!!!

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

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

相关文章

数据记笔记:USGS 查看上世纪卫星图

1 先到USGS EarthExplorer 界面&#xff0c;在address 处选择需要的城市/也可以在底下polygon处手动标出需要研究的区域 2&#xff0c;点击show&#xff0c;就会出找到的对应的区域&#xff0c;点击这个区域&#xff0c;polygon处就会有响应了。然后选择date range 3 点击下方的…

P1439 背包九讲(1):简单的0-1背包

P1439 背包九讲1&#xff1a;简单的0-1背包 一、原题呈现1、题目描述2、输入描述3、输出描述4、样例输入5、样例输出 二、思路分析这是一个最基础的01背包问题。 三、整体代码 一、原题呈现 1、题目描述 有一个箱子容量为 V&#xff08;正整数&#xff0c;0&#xff1c;&…

Java SE:集合

1. 单列集合顶层接口Collection 集合&#xff1a;将一个个数据结构写好封装成类&#xff0c;方便开发者调用 单列集合底下有两大接口&#xff1a;List和Set List底下有3个集合类&#xff1a;ArrayList&#xff08;数组&#xff09;、LinkedList&#xff08;链表&#xff09;…

【NI-DAQm入门】构建应用程序案例1

1.系统框图 2.应用框图 3. 代码结构 3.1 技巧1 使用模拟采样时钟作为编码器的时钟源•(而不是使用隐式) 同步模拟输入和编码 3.2 技巧2 为模拟输入和计数器输入采集样本 写入相同采样点至文件 对齐数据文件 3.3 技巧3 数字读写技巧

FLUENT Meshing Watertight Geometry工作流入门 - 7 共享拓扑

本视频中学到的内容&#xff1a; “共享拓扑”任务的工作细节如何使用“更新边界”和“更新区域”任务来更新边界和区域的属性 视频链接&#xff1a; FLUENT Meshing入门教程-7应用共享拓扑_哔哩哔哩_bilibili 【Import Geometry】 启动Ansys Fluent进入网格模式。在工作流类…

Swing程序设计(10)列表框,文本框,文本域,密码框

文章目录 前言一、列表框二、文本框&#xff08;域&#xff09; 1.文本框2.文本域三、密码框总结 前言 该篇文章简单介绍了Java中Swing组件里的列表框、文本框、密码框。 一、列表框 列表框&#xff08;JList&#xff09;相比下拉框&#xff0c;自身只是在窗体上占据固定的大小…

第三百四十九回

文章目录 1. 概念介绍2. 原理与方法2.1 知识对比2.2 使用方法 3. 示例代码4. 内容总结 我们在上一章回中介绍了"加密包crypto"相关的内容&#xff0c;本章回中将介绍characters包.闲话休提&#xff0c;让我们一起Talk Flutter吧。 1. 概念介绍 在项目中会遇到获取字…

Paper - CombFold: predicting structures of large protein assemblies 论文简读

欢迎关注我的CSDN&#xff1a;https://spike.blog.csdn.net/ 本文地址&#xff1a;https://spike.blog.csdn.net/article/details/136143199 CombFold: predicting structures of large protein assemblies using a combinatorial assembly algorithm and AlphaFold2 CombFold…

从物联网到数字孪生:智慧社区的演变

随着科技的飞速发展和数字化转型的深入推进&#xff0c;智慧社区已成为提升城市治理水平和居民生活质量的重要方向。在这一演变过程中&#xff0c;物联网和数字孪生技术起到了至关重要的作用。本文将深入探讨从物联网到数字孪生的演变过程&#xff0c;分析这一转变对智慧社区建…

EasyRecovery软件免费版与付费版有哪些功能区别?

免费版的EasyRecovery软件在功能和恢复能力上确实存在一些限制。 首先&#xff0c;在数据恢复方面&#xff0c;免费版通常只能恢复最多1GB的数据。这意味着&#xff0c;如果你需要恢复的数据量超过1GB&#xff0c;你将需要升级到付费版才能完全恢复。 其次&#xff0c;免费版…

LeetCode---384周赛

题目列表 3033. 修改矩阵 3034. 匹配模式数组的子数组数目 I 3035. 回文字符串的最大数量 3036. 匹配模式数组的子数组数目 II 一、修改矩阵 简单模拟即可&#xff0c;代码如下 class Solution { public:vector<vector<int>> modifiedMatrix(vector<vecto…

专业140+总分400+华中科技大学824信号与系统考研经验华科华中大电子信息与通信工程,真题,大纲,参考书。

今年考研落下帷幕&#xff0c;看到有人落寞&#xff0c;有人金榜题名&#xff0c;心里体会五谷杂陈&#xff0c;自己很幸运通过努力上岸华科&#xff0c;初试专业课824信号与系统140&#xff0c;数一130&#xff0c;总分400&#xff0c;对于这个成绩稍微有点超出自己预期&#…

ViT: transformer在图像领域的应用

文章目录 1. 概要2. 方法3. 实验3.1 Compare with SOTA3.2 PRE-TRAINING DATA REQUIREMENTS3.3 SCALING STUDY3.4 自监督学习 4. 总结参考 论文&#xff1a; An Image is Worth 16x16 Words: Transformers for Image Recognition at Scale 代码&#xff1a;https://github.com…

删除windows自带输入法

ctrl shift F 搜狗简繁体切换

【大厂AI课学习笔记】【2.1 人工智能项目开发规划与目标】(4)数据准备的流程

今天学习的是数据准备的流程。 我们已经知道&#xff0c;数据准备占了AI项目超过一半甚至79%的时间。 那么数据准备&#xff0c;都做些什么&#xff0c;有哪些流程。 1.数据采集 观测数据人工收集调查问卷线上数据库 2.数据清洗 有缺失的数据有重复的数据有内容错误的数据…

CSS的注释:以“ /* ”开头,以“ */ ”结尾

CSS的注释:以“ /* ”开头&#xff0c;以“*/”结尾 CSS的注释: 以“ /* ”开头&#xff0c;以“ */ ”结尾 在CSS中&#xff0c;注释是一种非常重要的工具&#xff0c;它们可以帮助开发者记录代码的功能、用法或其他重要信息。这些信息对于理解代码、维护代码以及与他人合作都…

SpringBoot实现OneDrive文件上传

SpringBoot实现OneDrive文件上传 源码 OneDriveUpload: SpringBoot实现OneDrive文件上传 获取accessToken步骤 参考文档&#xff1a;针对 OneDrive API 的 Microsoft 帐户授权 - OneDrive dev center | Microsoft Learn 1.访问Azure创建应用Microsoft Azure&#xff0c;使…

Sora 文生视频提示词实例集 2

Prompt: Historical footage of California during the gold rush. 加利福尼亚淘金热期间的历史影像。 Prompt: A close up view of a glass sphere that has a zen garden within it. There is a small dwarf in the sphere who is raking the zen garden and creating patter…

Ubuntu 20.04 安装RVM

RVM是管理Ruby版本的工具,使用RVM可以在单机上方便地管理多个Ruby版本。 下载安装脚本 首先使下载安装脚本 wget https://raw.githubusercontent.com/rvm/rvm/master/binscripts/rvm-installer 如果出现了 Connection refused 的情况, 可以考虑执行以下命令修改dns,再执…

win10下wsl2使用记录(系统迁移到D盘、配置国内源、安装conda环境、配置pip源、安装pytorch-gpu环境、安装paddle-gpu环境)

wsl2 安装好后环境测试效果如下&#xff0c;支持命令nvidia-smi&#xff0c;不支持命令nvcc&#xff0c;usr/local目录下没有cuda文件夹。 系统迁移到非C盘 wsl安装的系统默认在c盘&#xff0c;为节省c盘空间进行迁移。 1、输出wsl -l 查看要迁移的系统名称 2、执行导出命…