0
点赞
收藏
分享

微信扫一扫

【宽度优先搜索】计蒜客:蒜头君回家(带条件的BFS)

凛冬已至夏日未远 2022-02-14 阅读 61

 8 10
P.####.#P#
..#..#...#
..#T##.#.#
..........
..##.#####
..........
#####...##
###....S##

21

求最短步数一般用BFS:

带条件的BFS:

起点为S,终点为T,到达终点时判断是否经过了P(同时满足两个条件返回)

标记数组使用三维:

vis[x][y][flag]

vis多开一维度表示是否已经取得了钥匙的状态。

如果到达终点并且取得钥匙的状态被标记,bfs 结束。

  同一个点其实可以走两次,第一次是没拿到钥匙的时候,第二次是拿到钥匙的时候?

代码:

#include<iostream>
#include<vector>
#include<string>
#include<queue>
#include<cstring>
using namespace std;
int n,m;
vector<string>G;
bool vis[2001][2001][2];
struct state{
	int x,y;
	int step;
	bool flag;
	state(int _x,int _y,int _step,bool _flag){
		x=_x;
		y=_y;
		step=_step;
		flag=_flag;
	}
};
 
void input(){
	cin>>n>>m;
	for(int i=0;i<n;i++){
		string s;
		cin>>s;
		G.push_back(s); 
	}
	memset(vis,false,sizeof(vis));
}
void bfs(int x,int y){
	queue<state>q;
	q.push(state(x,y,0,false));
	while(!q.empty()){

		state cur=q.front();
		q.pop();
        int x=cur.x;
		int y=cur.y;
		int step=cur.step;
		bool flag=cur.flag;
		if(G[x][y]=='P'){
			flag=true;

		}
		if(G[x][y]=='T'&&flag==true){
			cout<<"步数:"<<step<<endl;
			return;
		}
	
		vis[x][y][flag]=true;

		if(x+1<n&&!vis[x+1][y][flag]&&G[x+1][y]!='#'){
			vis[x+1][y][flag]=true; 
			q.push(state(x+1,y,step+1,flag));
		}
		if(x-1>=0&&!vis[x-1][y][flag]&&G[x-1][y]!='#'){
			vis[x-1][y][flag]=true;
			q.push(state(x-1,y,step+1,flag));
		}
		if(y-1>=0&&!vis[x][y-1][flag]&&G[x][y-1]!='#'){
			vis[x][y-1][flag]=true;
			q.push(state(x,y-1,step+1,flag));
		}
		if(y+1<m&&!vis[x][y+1][flag]&&G[x][y+1]!='#'){
			vis[x][y+1][flag]=true;
			q.push(state(x,y+1,step+1,flag));
		}
	
		         		
	}
}
void output(){
	for(int i=0;i<n;i++){
		cout<<G[i]<<endl;
	}
}
void solve(){
	for(int i=0;i<n;i++){
		for(int j=0;j<m;j++){
			if(G[i][j]=='S'){
				bfs(i,j);
				return;
			}
		}
	}
	
} 
int main(){
	input();
    solve();
}

举报

相关推荐

0 条评论