看到其它題解都是數組模拟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;
}
總得來說,題目還是比較簡單的,就是闆子題,細節很多,很容易寫錯