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

广度优先搜索算法笔记

广度优先搜索

上一回我们讲了深度优先搜索,那么这会我们来讲一讲他的好兄弟,也就是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.kler.cn/a/530203.html

相关文章:

  • DeepSeek Janus-Pro:多模态AI模型的突破与创新
  • w186格障碍诊断系统spring boot设计与实现
  • 【自然语言处理(NLP)】基于Transformer架构的预训练语言模型:BERT 训练之数据集处理、训练代码实现
  • 解决whisper 本地运行时GPU 利用率不高的问题
  • DeepSeek r1本地安装全指南
  • 29.Word:公司本财年的年度报告【13】
  • 政务行业审计文件大数据高速报送解决方案
  • 跨越通信障碍:深入了解ZeroMQ的魅力
  • deep seek R1本地化部署及openAI API调用
  • 别做太远的规划
  • nodejs:express + js-mdict 网页查询英汉词典,能播放声音
  • 【数据分析】案例03:当当网近30日热销图书的数据采集与可视化分析(scrapy+openpyxl+matplotlib)
  • 【小鱼闪闪】做一个物联网控制小灯的制作流程简要介绍(图文)
  • OpenAI开源战略反思:中国力量推动AI产业变革
  • 【漫话机器学习系列】076.合页损失函数(Hinge Loss)
  • 【算法-位运算】位运算遍历 LogTick 算法
  • 基于机器学习鉴别中药材的方法
  • python小知识-jupyter lab
  • 海外问卷调查渠道查,具体运营的秘密
  • 【leetcode100】路径总和Ⅲ
  • DS常识问答:人民币升值贬值是什么回事
  • w188校园商铺管理系统设计与实现
  • 笔试-排列组合
  • it基础使用--5---git远程仓库
  • 如果通过认证方式调用Sf的api
  • 动态函数调用和模拟