AT168 自宅からの脱出
看到其它题解都是数组模拟BFS,没人用STL的
那我就来写一写STL吧
sol
题目意思都很清晰吧,分为两个部分:
①从我的房间到电脑
②从电脑到我家的门
求最短距离,很明显用两遍BFS即可,“#”表示障碍(即不能走),“S”表示我的房间,“C”电脑位置,“G”表示我家的门。首先就把S,C,G的位置循环搜出来
然后呢,跑两遍BFS,第一次起点为S,终点为C,第二次起点为C,终点为G。注意:在第二次开始搜的时候数组一定要清空
code
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<queue>
typedef long long ll;
using namespace std;
inline int max(int a,int b){return a>b?a:b;}
inline int min(int a,int b){return a<b?a:b;}
inline int rd(){
int res=0,sign=1;char ch;
while((ch=getchar())<'0'||ch>'9')if(ch=='-')sign=-1;res=res*10+ch-48;
while((ch=getchar())>='0'&&ch<='9')res=res*10+ch-48;
return res*sign;
}
const int maxn=510;
int n,m;//边长
int dx[5]={0,0,1,-1};
int dy[5]={1,-1,0,0};//方向数组,表示下一步的四个方向
char mapp[maxn][maxn];//存储我家
int ans[maxn][maxn];//记录步数
bool flag[maxn][maxn];//标记是否走过
int sx,sy,cpx,cpy,ex,ey;//sx、sy表示S(我的房间),cpx、cpy表示C(电脑),ex、ey表示G(我家的门)
queue<int>q1,q2;//定义队列
queue<int>qq1,qq2;//因为STL队列不能清空(只有双端队列才能清空),所以定义两个
void init(){//读入
n=rd(),m=rd();
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++){
cin>>mapp[i][j];
if(mapp[i][j]=='S') sx=i,sy=j;
if(mapp[i][j]=='C') cpx=i,cpy=j;
if(mapp[i][j]=='G') ex=i,ey=j;//把S、C、G坐标搜出来
}
}
int sum=0;
bool used=false,t=false;
void BFS1(){//第一遍BFS,从S到C
memset(flag,0,sizeof(flag));
memset(ans,0,sizeof(ans));
used=false;
q1.push(sx),q2.push(sy);
flag[sx][sy]=1;
while(!q1.empty()){
int x=q1.front(),y=q2.front();
q1.pop(),q2.pop();
if(x==cpx&&y==cpy){
sum+=ans[x][y];
used=1;//如果能到达目的地,标记起来
}
for(int i=0;i<4;i++){
int xx1=x+dx[i];
int yy1=y+dy[i];
if(xx1>=1&&xx1<=n&&yy1>=1&&yy1<=m&&mapp[xx1][yy1]!='#'&&!flag[xx1][yy1]){
flag[xx1][yy1]=1;
ans[xx1][yy1]=ans[x][y]+1;
q1.push(xx1),q2.push(yy1);
}
}
if(used)break;
}
if(!used)//如果不能到 ,输出-1
puts("-1"),t=1;
}
void BFS2(){//第二遍BFS,从C到G
memset(flag,0,sizeof(flag));
memset(ans,0,sizeof(ans));
used=false;
qq1.push(cpx),qq2.push(cpy);
flag[cpx][cpy]=1;
while(!qq1.empty()){
int x=qq1.front(),y=qq2.front();
qq1.pop(),qq2.pop();
if(x==ex&&y==ey){
sum+=ans[x][y];
used=1;//同上
}
for(int i=0;i<4;i++){
int xx1=x+dx[i];
int yy1=y+dy[i];
if(xx1>=1&&xx1<=n&&yy1>=1&&yy1<=m&&mapp[xx1][yy1]!='#'&&!flag[xx1][yy1]){
flag[xx1][yy1]=1;
ans[xx1][yy1]=ans[x][y]+1;
qq1.push(xx1),qq2.push(yy1);
}
}
if(used)break;
}
if(!used)
puts("-1"),t=1;//同上
}
int main(){
init();
BFS1();
if(t)return 0;//如果不能到就退出程序
t=false;
BFS2();
if(t)return 0;//同上
cout<<sum<<endl;//完美输出
return 0;
}
总得来说,题目还是比较简单的,就是板子题,细节很多,很容易写错