广度优先搜索算法笔记

ops/2025/2/3 9:04:01/

广度优先搜索

上一回我们讲了深度优先搜索,那么这会我们来讲一讲他的好兄弟,也就是bfs。那么上一回我们知道dfs是不撞南墙不回头,也就是一条路走到底。但是广搜不一样,他是一层一层的搜索,就是一颗树的样子,第一层是 1 1 1,第二层是 2 , 3 2,3 2,3,第三层是 4 , 5 , 6 , 7 4,5,6,7 4,5,6,7

那么bfs的遍历顺序就是1->2/3->4/5/6/7。所以我们不难看出广搜的一个很好的性质,就是方便找最短路径。所以通常广搜也用来寻找最短的一个路径和长度。那么同时我们换一种方法来考虑,从起点出发,类似于泼水一般,让水流顺着多个方向同时蔓延。这种方法被称为洪泛法。通常也就是使用bfs来实现的。

那么怎么实现bfs呢?通常就是使用队列来维护,也就是先进先出的特性。比方说还是上面那张图片。我们就是先把 1 1 1 入队,这是第一步,然后下一步的话就是先把他自己弹出,然后把它下一层的 2 , 3 2,3 2,3 入队,这样就可以保证每次搜索一层了。那么就下来我给大家贴一下模版。

push(初始状态)// 将初始状态入队
while (!q.empty()) {state u = q.front()// 取出队首q.pop()//出队for(...) 1/找到u的所有可达状态v更新数据if...)//v需要满足某些条件,如未访问过、未在队内等q·push(v)// 入队 (同时可能需要维护某些必要信息)

那么接下来我们就来讲一下经典的例题

魔板 Magic Squares

我们知道魔板的每一个方格都有一种颜色。这 8 8 8 种颜色用前 8 8 8 个正整数来表示。可以用颜色的序列来表示一种魔板状态,规定从魔板的左上角开始,沿顺时针方向依次取出整数,构成一个颜色序列。对于上图的魔板状态,我们用序列 { 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 } \{1,2,3,4,5,6,7,8\} {1,2,3,4,5,6,7,8} 来表示。这是基本状态。

这里提供三种基本操作,分别用大写字母 A \text A A B \text B B C \text C C 来表示(可以通过这些操作改变魔板的状态):

A \text A A:交换上下两行;

B \text B B:将最右边的一列插入最左边;

C \text C C:魔板中央四格作顺时针旋转。

下面是对基本状态进行操作的示范:

A \text A A

8 7 6 5 8\quad7\quad6\quad5 8765

1 2 3 4 1\quad2\quad3\quad4 1234

B \text B B

4 1 2 3 4\quad1\quad2\quad3 4123

5 8 7 6 5\quad8\quad7\quad6 5876

C \text C C

1 7 2 4 1\quad7\quad2\quad4 1724

8 6 3 5 8\quad6\quad3\quad5 8635

对于每种可能的状态,这三种基本操作都可以使用。

你要编程计算用最少的基本操作完成基本状态到目标状态的转换,输出基本操作序列。


那么这道题目我认为一个难点就在于如何想象到时广搜,那么其实这里可以抽象成一行行字符串代表成为当前的状态。所以我们每一次都是搜索当前进行三种操作的哪一种就可以了。然后我们就需要注意一个坑点:万一回来呢了?也就是说万一通过一些操作,有返回到之前的一个节点上,这就出现死循环了,所以我们需要使用map来进行一个映射关系,自动去重。那么计算最短操作序列的长度,也就是map中统计关键字出现的次数,然后输出此长度即可。
count函数来判断关键字是否出现,返回值为 0 0 0 1 1 1
输出map的长度采用size函数完成;然后就给大家上一份代码,广搜的结构较为模版,代码长的也差不多,就写一道题就好了。

#include<bits/stdc++.h>
using namespace std;
string a;
map<string,string>m;
queue<string>q;
void A(string x)
{string xx=x;for(int i=0;i<4;i++){char x1=x[i];x[i]=x[7-i];x[7-i]=x1;}if(m.count(x)==0){q.push(x);m[x]=m[xx]+'A';}return;
}
void B(string x)
{string xx=x;x[0]=xx[3],x[1]=xx[0],x[2]=xx[1],x[3]=xx[2],x[4]=xx[5],x[5]=xx[6],x[6]=xx[7],x[7]=xx[4];if(m.count(x)==0){q.push(x);m[x]=m[xx]+'B';}return;
}
void C(string x)
{string xx=x;x[1]=xx[6],x[2]=xx[1],x[5]=xx[2],x[6]=xx[5];if(m.count(x)==0){q.push(x);m[x]=m[xx]+'C';}return;
}
void bfs()
{q.push("12345678");m["12345678"]="";while(q.empty()==false){A(q.front());B(q.front());C(q.front());if(m.count(a)!=0){cout<<m[a].size()<<endl<<m[a];return;}q.pop();}return;
}
int main()
{for(int i=0;i<8;i++){char a1;cin>>a1;a+=a1;getchar();}bfs();return 0;
}

http://www.ppmy.cn/ops/155266.html

相关文章

[paddle] 矩阵相关的指标

行列式 det 行列式定义参考 d e t ( A ) ∑ i 1 , i 2 , ⋯ , i n ( − 1 ) σ ( i 1 , ⋯ , i n ) a 1 , i 1 a 2 , i 2 , ⋯ , a n , i n det(A) \sum_{i_1,i_2,\cdots,i_n } (-1)^{\sigma(i_1,\cdots,i_n)} a_{1,i_1}a_{2,i_2},\cdots, a_{n,i_n} det(A)i1​,i2​,⋯,in​…

【DeepSeek】本地快速搭建DeepSeek

博主未授权任何人或组织机构转载博主任何原创文章&#xff0c;感谢各位对原创的支持&#xff01; 博主链接 博客内容主要围绕&#xff1a; 5G/6G协议讲解 高级C语言讲解 Rust语言讲解 文章目录 本地快速搭建DeepSeek一、安装及配置ollama二、DeepSeek模型…

数字化创新者如何利用开源2+1链动模式AI智能名片S2B2C商城小程序源码重塑市场地位

摘要&#xff1a;在数字化转型的浪潮中&#xff0c;数字化创新者正通过整合前沿技术&#xff0c;重塑行业格局&#xff0c;引领市场变革。本文深入探讨了开源21链动模式、AI智能名片以及S2B2C商城小程序源码等技术在数字化创新中的应用&#xff0c;旨在揭示这些技术如何助力企业…

VSCode设置内容字体大小

1、打开VSCode软件&#xff0c;点击左下角的“图标”&#xff0c;选择“Setting”。 在命令面板中的Font Size处选择适合自己的字体大小。 2、对比Font Size值为14与20下的字体大小。

【工欲善其事】利用 DeepSeek 实现复杂 Git 操作:从原项目剥离出子版本树并同步到新的代码库中

文章目录 利用 DeepSeek 实现复杂 Git 操作1 背景介绍2 需求描述3 思路分析4 实现过程4.1 第一次需求确认4.2 第二次需求确认4.3 第三次需求确认4.4 V3 模型&#xff1a;中间结果的处理4.5 方案验证&#xff0c;首战告捷 5 总结复盘 利用 DeepSeek 实现复杂 Git 操作 1 背景介绍…

利用ue5制作CG动画笔记

tips&#xff1a; 按住鼠标中键可以拖动枢轴点 在曲线编辑器中按住shift可以使曲线编辑保持在x轴 专业术语&#xff1a; CGI&#xff1a;计算机生成图象&#xff08;computer-generated imagery&#xff09;真实的不算&#xff0c;计算机生成的 Compositing&#xff1a;合…

科技快讯 | 领英“隐私风波”告一段落;华为余承东智驾 1345 公里返工,称智界 R7 打赢“鸡蛋保卫战”;谷歌翻译将增“提问”功能

谷歌安卓 16 快捷设置被曝告别悬浮窗&#xff0c;选项在面板内展开 科技媒体Android Authority于1月30日发布博文&#xff0c;称谷歌安卓16更新中&#xff0c;快捷面板&#xff08;Quick Setting&#xff09;功能可能回归旧版样式。当前安卓版Quick Setting点击磁贴会扩展为浮动…

Golang 并发机制-4:用Mutex管理共享资源

并发性是Go的强大功能之一&#xff0c;它允许多个线程&#xff08;并发线程&#xff09;同时执行。然而&#xff0c;权力越大&#xff0c;责任越大。当多个例程并发地访问和修改共享资源时&#xff0c;可能会导致数据损坏、竞争条件和不可预测的程序行为。为了解决这些问题&…