初步了解bfs()

了解背景:那是一个我也不知道是什么时候了,视频链接https://www.bilibili.com/video/BV1sC4y1k74R/?spm_id_from=333.1007.top_right_bar_window_default_collection.content.click&vd_source=40e0f7ad539853d31c00348fac6dd1ec
跟这视频学大致会明白bfs()是干什么的(我也不是很清楚),反正就是个搜索。
基本的模板大致是这样吧

点击查看代码
queue<int>q;
q.push(初始状态);
while(!q.empty())
{
	a=q.front();
	q.pop();
	if(a满足条件)
	{
		执行操作; 
	} 
	剩下的内容看题目来;
	q.push(v); 
} 

bfs()做到现在也算做了几题,也是把这几题分成2个类吧,也不能说是两类。第二种也只能算是第一种的延续
第一种就是最短路径的问题(最优的解) 像奇怪的电梯和赛马
第二种bfs()使用是都会有一个数组来判断这个方位是不是遍历过,第二种的做法就是加深这个数组的应用。(我的想法是这样的)
那我就针对这两种类给出两个例题
1 迷宫https://ac.nowcoder.com/acm/problem/24554

点击查看代码
#include<bits/stdc++.h>
using namespace std;
int dir[4][2]={{1,0},{-1,0},{0,1},{0,-1}};//四个方向
int num[200][200];
int va[200][200]={0};
int n,m;
struct pos{
	int x,y;
};
bool bor(int x,int y)//边界搜素 
{
	return x>=1&&x<=n&&y>=1&&y<=m?1:0;
}
void bfs()
{
	pos cur,nex;
	queue<pos>p;
	cur.x=1;
	cur.y=1;
	p.push(cur);
	va[1][1]=1;
	while(!p.empty())
	{
		cur=p.front();
		p.pop();
		if(cur.x==n&&cur.y==m)
		{
			cout<<"YES\n";
			return ;
		}
		for(int i=0;i<4;i++)
		{
			int xx=cur.x+dir[i][0];
			int yy=cur.y+dir[i][1];
			if(bor(xx,yy)&&num[xx][yy]==0)
			{
				if(va[xx][yy]==0)
				{
					va[xx][yy]=1;
					nex.x=xx;
					nex.y=yy;
					p.push(nex);
				}
			}
		}
	}
	cout<<"NO"<<endl;
	return ;
}
int main()
{
	cin>>n>>m;
	for(int i=1;i<=n;i++)
	{
		for(int j=1;j<=m;j++)
		{
			cin>>num[i][j];
		}
	}
	bfs();
	return 0;
}

2 01迷宫https://ac.nowcoder.com/acm/problem/219509

点击查看代码
#include<bits/stdc++.h>
using namespace std;
int num[505][505];
int route[505][505];
/*
route可以代替vis的作用的原因是因为两者的作用大差不差
都是起到判断作用,但route多了一个记录方位的作用 
*/
string dirStr="DULR";
// i=0下 i=1上 i=2左 i=3右 
int n,m;
int sx,sy,ex,ey;
int dir[4][2]={{0,1},{0,-1},{-1,0},{1,0}};//四个方向:下上左右这4个方向
//起点 = -2 , 未遍历 = -1, 空地 = 0, 障碍 = 1
struct pos{
	int x,y;
	int step;
};
bool bor(int x,int y)//边界搜素+是否是障碍+是否遍历 
{
	return x>=1&&x<=n&&y>=1&&y<=m&&route[x][y]==-1&&num[x][y]==0?1:0;
}
/*
用栈来实现,先进后出
通过逆运算来实现到下一个点
(2,2)存的 R 位移量是(0,1),使用逆运算
(2,2) - (0,1) 就可以逆运算,算出上一步在 (2,1)位置 
*/
void printdir() 
{
	stack<int>q;
	q.push(route[ex][ey]);
	int dx=ex,dy=ey;
	while(q.top()!=-2)
	{
		int d=q.top();
		dx=dx-dir[d][0];
		dy=dy-dir[d][1];
		q.push(route[dx][dy]);
	}
	q.pop();//弹出起点
	while(!q.empty())
	{
		cout<<dirStr[q.top()];
		q.pop();
	}
	cout<<endl;
	return ;
}
void bfs()
{
	pos cur,nex;
	queue<pos>p;
	if(num[sx][sy]==1||num[ex][ey]==1)
	{
		cout<<-1<<endl;
		return ;
	}
	route[sx][sy]=-2;
	cur.x=sx;
	cur.y=sy;
	cur.step=0;
	p.push(cur);
	while(!p.empty())
	{
		cur=p.front();
		p.pop();
		if(cur.x==ex&&cur.y==ey)
		{
			cout<<cur.step<<endl;
			printdir();
			return ;
		}
		int newstep=cur.step+1;
		for(int i=0;i<4;i++)
		{
			int xx=cur.x+dir[i][0];
			int yy=cur.y+dir[i][1];
			if(bor(xx,yy))
			{
				route[xx][yy]=i;
				nex.x=xx;
				nex.y=yy;
				nex.step=newstep;
				p.push(nex);
			}
		}
	}
	cout<<-1<<endl;
	return ;
}
int main()
{
	cin>>n>>m;
	memset(route,-1,sizeof route);//赋值-1,让route为未赋值状态 
	for(int i=1;i<=n;i++)
	{
		for(int j=1;j<=m;j++)
		{
			scanf("%1d",&num[i][j]);
			//这个输入太恶毒了,搞了半天,原来是这里出问题了,按一位输入
		}
	}
	cin>>sx>>sy>>ex>>ey;
	bfs();
	return 0;
}
posted on 2024-02-02 09:57  咋瓦鲁多_食我压路机  阅读(0)  评论(0)    收藏  举报