AT_abc387_d 题解
题目传送门
思路
可以使用 bfs 解决此题。
与普通 bfs 不同,这道题遍历需要横纵交替。于是可以在 bfs 队列中增加一维,表示上一次操作是横还是纵。在下一次进入时,就可以根据队列中新增的一维来判断应该横向走还是纵向走。
bfs 的时间复杂度为
AC CODE
#include<bits/stdc++.h>
using namespace std;
#define int long long
int read(){int x=0;char f=1,ch=getchar();while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}while(ch>='0'&&ch<='9')x=x*10+ch-'0',ch=getchar();return x*f;}
const int N=1e3+10;
int dx1[]={0,0,0},dy1[]={0,-1,1};
int dx2[]={0,-1,1},dy2[]={0,0,0};
struct node{
int x,y,flag;
};queue<node>q;
char s[N][N];
bool vis[N][N][2];
signed main(){
int h=read(),w=read();
for(int i=1;i<=h;++i)
scanf("%s",s[i]+1);
int bx,by,ex,ey;
for(int i=1;i<=h;++i)
for(int j=1;j<=w;++j)
if(s[i][j]=='S')
bx=i,by=j;
else if(s[i][j]=='G')
ex=i,ey=j;
q.push({bx,by,0}),q.push({bx,by,1});
vis[bx][by][0]=true,vis[bx][by][1]=true;
int dis=0;
while(!q.empty()){
int n=q.size();
while(n--){
node u=q.front();q.pop();
int x=u.x,y=u.y,op=u.flag;
if(x==ex&&y==ey)
return printf("%lld\n",dis),0;
if(!op)
for(int i=1;i<=2;++i){
int xx=x+dx1[i],yy=y+dy1[i];
if(xx>=1&&xx<=h&&yy>=1&&yy<=w&&s[xx][yy]!='#'&&!vis[xx][yy][1]){
vis[xx][yy][1]=true;
q.push({xx,yy,1});
}
}
else for(int i=1;i<=2;++i){
int xx=x+dx2[i],yy=y+dy2[i];
if(xx>=1&&xx<=h&&yy>=1&&yy<=w&&s[xx][yy]!='#'&&!vis[xx][yy][0]){
vis[xx][yy][0]=true;
q.push({xx,yy,0});
}
}
}
++dis;
}
printf("-1\n");
return 0;
}