对于BFS的一些疑惑
首先,BFS是从中心向四个方向蔓延过去,之前首先看到的是leetcode推箱子力扣推箱子的这段定义结构体的最优队列的BFS
class Solution {
public:
struct Node{
Node(int x0,int y0,int bx0,int by0){
x=x0;y=y0;
bx=bx0;by=by0;
}
int x,y;
int bx,by;
friend bool operator < (const Node a,const Node b){
if(a.x!=b.x) return a.x<b.x;
if(a.y!=b.y) return a.y<b.y;
if(a.bx!=b.bx) return a.bx<b.bx;
return a.by<b.by;
}
};
int cx[4]={0,1,0,-1};
int cy[4]={1,0,-1,0};
map<Node,int>dis;
map<Node,bool>inQue;
int minPushBox(vector<vector<char>>& grid) {
int n=grid.size(),m=grid[0].size();
int sx,sy,ex,ey,bx,by;
for(int i=0;i<n;i++)
for(int j=0;j<m;j++){
if(grid[i][j]=='T') ex=i,ey=j,grid[i][j]='.';
if(grid[i][j]=='S') sx=i,sy=j,grid[i][j]='.';
if(grid[i][j]=='B') bx=i,by=j,grid[i][j]='.';
}
dis.clear();inQue.clear();
queue<Node>Q;
while(!Q.empty()) Q.pop();
Node p(sx,sy,bx,by);
Q.push(p);
inQue[p]=true;
dis[p]=0;
int ans=-1;
while(!Q.empty()){
int x=Q.front().x,y=Q.front().y,bx=Q.front().bx,by=Q.front().by,count=dis[Q.front()];
inQue[Q.front()]=false;
Q.pop();
if(bx==ex&&by==ey){
if(ans>count||ans==-1) ans=count;
continue;
}
for(int i=0;i<4;i++)
{
int flag=0;
int nx=x+cx[i],ny=y+cy[i];
int nbx=bx,nby=by;
if(nx<0||nx>=n||ny<0||ny>=m) continue;
if(grid[nx][ny]=='#') continue;
if(nx==bx&&ny==by){
if(bx+cx[i]<0||bx+cx[i]>=n||by+cy[i]<0||by+cy[i]>=m) continue;
if(grid[bx+cx[i]][by+cy[i]]=='.') nbx+=cx[i],nby+=cy[i],flag=1;
}
Node temp(x+cx[i],y+cy[i],nbx,nby);
if(dis.count(temp)==0||dis[temp]>count+flag){
dis[temp]=count+flag;
if(!inQue[temp])
{
inQue[temp]=true;
Q.push(temp);
}
}
}
}
return ans;
}
};
这个是用map来存某个状态的最短次数,还有一个inQue来判断某个状态是否入队,因为已经入队的话就没必要再次入队了。因为这个的最短次数是不均匀的即不是从小到大排列的,所以需要对比所有到终点的路径然后选择最小次数的那个。而后来我在2015蓝桥杯有一题叫穿越雷区
这个的话其实是DFS和BFS都能用,然后在我用BFS的时候我发现因为这种距离是均匀的,先是把距离为1的全遍历完,接下来是把距离为2的全遍历完,所以只要能走到终点,第一条路一定是路径最短的了,而且在进行队列优化的时候,只要注意走过的路不要再走就行了,这样想变得简单很多。附上优化的代码
#include<iostream>
#include<vector>
#include<cstring>
#include<queue>
using namespace std;
struct Node{
Node(int x0,int y0){
x=x0;y=y0;
}
int x,y;
};
int sx,sy,ex,ey;
bool vis[105][105];
int dist[105][105];
int dx[4]={0,1,0,-1};
int dy[4]={1,0,-1,0};
int Solve(vector<string>grid){
int n=grid.size();
memset(vis,false,sizeof(vis));
dist[sx][sy]=0;
vis[sx][sy]=true;
queue<Node>que;
while(!que.empty()) que.pop();
que.push(Node(sx,sy));
while(!que.empty()){
Node v=que.front();que.pop();
int cx=v.x,cy=v.y,step=dist[cx][cy];
if(cx==ex&&cy==ey) return step;
for(int k=0;k<4;k++){
int vx=cx+dx[k];
int vy=cy+dy[k];
if(vx<0||vy<0||vx>=n||vy>=n||vis[vx][vy]||grid[cx][cy]==grid[vx][vy]) continue;
dist[vx][vy]=step+1;
vis[vx][vy]=true;
que.push(Node(vx,vy));
}
}
return -1;
}
int main(){
int num; cin>>num;
vector<string>grid(num,"");
for(int i=0;i<num;i++)
for(int j=0;j<num;j++){
char c;cin>>c;
if(c=='A') sx=i,sy=j;
else if(c=='B') ex=i,ey=j;
grid[i]+=c;
}
int ans=Solve(grid);
cout<<ans;
return 0;
}