SDJZUOJ迷宮問題(BFS)
阿新 • • 發佈:2019-02-04
題目描述
小明置身於一個迷宮,請你幫小明找出從起點到終點的最短路程。
小明只能向上下左右四個方向移動。
輸入格式
輸入包含多組測試資料。輸入的第一行是一個整數T,表示有T組測試資料。
每組輸入的第一行是兩個整數N和M(1<=N,M<=100)。
接下來N行,每行輸入M個字元,每個字元表示迷宮中的一個小方格。
字元的含義如下:
‘S’:起點
‘E’:終點
‘-’:空地,可以通過
‘#’:障礙,無法通過
輸入資料保證有且僅有一個起點和終點。
輸出
對於每組輸入,輸出從起點到終點的最短路程,如果不存在從起點到終點的路,則輸出-1。
樣例輸入
1
5 5
S-###
-----
##---
E#---
---##
樣例輸出
9
</pre><pre name="code" class="cpp">/* 1 5 5 S-### ----- ##--- E#--- ---## */ #include<stdio.h> #include<iostream> using namespace std; struct note { int x;//橫座標 int y;//縱座標 int s;//走的步數 }; struct note que[2051]; char a[51][51]; int i,j,k,n,m,startx,starty,p,q,ty,tx,flag; int book[51][51]; int next[4][2]={{0,1}, {1,0}, {0,-1}, {-1,0}}; void bfs() { //佇列初始化 int head=1; int tail=1; //往佇列插入迷宮的入口座標 que[tail].x=startx; que[tail].y=starty; que[tail].s=0; tail++; book[startx][starty]=1; flag=0;//用來標記是否到達目的地,0表示沒有 while(head<tail)//當佇列不為空時候 { //列舉四個方向(注意方向陣列的設定和for迴圈的遍歷,通用模板) for(k=0;k<=3;k++) { //計算下一個點座標 tx=que[head].x+next[k][0]; ty=que[head].y+next[k][1]; //判斷是否越界 if(tx<1||tx>n||ty<1||ty>n) continue; //判斷是否是障礙物或者已經在路徑中 if(a[tx][ty]!='#'&&book[tx][ty]==0)//此處不能寫 a[tx][ty]=='-',因為這樣起點就進不了佇列中 { //把這個點標記為已經走過 //注意寬頻搜尋每個點只能入佇列一次 ,和dfs不同,所以book的值不需要恢復為0; book[tx][ty]=1; //插入新的點到佇列中 que[tail].x =tx; que[tail].y=ty; que[tail].s=que[head].s+1; tail++; } //如果到了目的地,停止擴充套件,任務結束,退出迴圈 if(tx==p&&ty==q) { //注意這兩句話千萬位置不能顛倒 flag=1; break; } } if(flag==1) break; head++;//這個地方千萬不能忘記,當一個點擴充套件結束後,head++才能使得後面的點再進行擴充套件 } //列印佇列中末尾最後一個點的步數 //注意tail是指向隊尾的下一個位置,所以需要-1 cout<<que[tail-1].s; } int main() { cin>>n>>m; for(i=1;i<=n;i++) { for(j=1;j<=m;j++) { cin>>a[i][j]; if(a[i][j]=='S') { startx=i; starty=j; } if(a[i][j]=='E') { p=i; q=j; } } } bfs(); return 0; }