BFS题目练习

BFS
题型:出现起点,出现终点
用法:一层一层搜索,每一层与起点的距离等长
如:
如图
先 1 入队
1 出队
1的连接点 2,3,4入队
2,3,4依次出队
2,3,4的连接点5,9,7,8,6依次入队

以此类推
每次入队和出队的都是一层一层的

1、走迷宫
https://www.acwing.com/problem/content/846/

#include<bits/stdc++.h>
using namespace std;
int n,m; 
int a[101][101];
int k[101][101];
struct node{
    
    
	int x,y;
}p;
queue<node> q; 
//x上至下 y左至右
//上 下 左  右 
int dir[4][2]={
    
    1,0,-1,0,0,-1,0,1};
int bfs(){
    
    
	int res = 0;
	//第一个点入队
	q.push({
    
    0,0});
	//当队列有元素存在 
	while(!q.empty()){
    
    
	
		p=q.front();//取出q的顶点元素
		q.pop();//释放
		
		int dx ,dy;
		for(int i=0;i<4;++i){
    
    
			dx=p.x+dir[i][0],dy=p.y+dir[i][1];
			if(dx<0||dy>=m||dx>=n||dy<0||k[dx][dy]||a[dx][dy]==1){
    
    
				//越界||为墙||走过
				continue;	
			}
			//在上一层的基础上 + 1 (离起点的距离加1)
			k[dx][dy]=k[p.x][p.y]+1;
			//入队
			q.push({
    
    dx,dy});
		}
		
		
	} 

	return k[n-1][m-1];
}
int main(){
    
    
	cin>>n>>m;
	for(int i=0;i<n;++i)
		for(int j=0;j<m;++j) 
			cin>>a[i][j];
	cout<<bfs();
	return 0;
} 

2、八数码
https://www.acwing.com/problem/content/847/

注意点:
<1 记录出现过的状态—可使用变进制数
<2 一维数组与二维数组的相互转化

#include<iostream>
#include<queue>
#include<algorithm>
#include<string>
using namespace std;
const int N = 4*1e5 + 10;
bool vis[N];
string start;
int fact[9]={
    
    1};
struct point{
    
    
    int step;//记录步数
    string s;
};

int dx[4]={
    
    1,0,-1,0},dy[4]={
    
    0,1,0,-1};
//变进制数--逢i进1
//根据逆序对个数
int hash_map(string s){
    
    
    int res = 0;
    for(int i=0;i<9;++i){
    
    
        int k =0;
        for(int j=0;j<i;++j){
    
    
            if(s[j]>s[i]) k++;
        }
        res+=k*fact[i];
    }
    return res;
}
int bfs(){
    
    
    vis[hash_map(start)]=true;
    
    point p;
    p.s = start;
    p.step = 0;
    
    string end = "12345678x";

    queue<point>q;
    q.push(p);
    
    while(!q.empty()){
    
    
        p = q.front();
        q.pop();
        
        int distance = p.step;
        
        if(p.s==end) return distance;
        
        //x位置
        int k = (p.s).find('x');
        
        //一维化二维
        
        int x =  k/3;
        int y =  k%3;
        
        
        for(int i=0;i<4;++i){
    
    
            int nx = x+dx[i],ny = y+dy[i];
            
            if(nx<0||nx>=3||ny<0||ny>=3) continue;
            
            //二维化一维
            swap(p.s[k],p.s[nx*3+ny]);
            
            int h = hash_map(p.s);
            if(!vis[h]){
    
    
                vis[h]=true;
                p.step=distance +1;
                q.push(p);
            }
            
            swap(p.s[k],p.s[nx*3+ny]);
            
        }
    }
    return -1;
}
int main(){
    
    
    //初始化变进制数
    //i!初始化
    for(int i=1;i<9;++i) fact[i]=fact[i-1]*i;
    fact[0]=0;
    char c;
    for(int i=0;i<9;++i){
    
    
        cin>>c;
        start+=c;
    }
    cout<<bfs();
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_44922497/article/details/114144478