nyoj-題目58-最少步數【DFS】
阿新 • • 發佈:2019-02-06
最少步數
時間限制:3000 ms | 記憶體限制:65535 KB 難度:4- 描述
-
這有一個迷宮,有0~8行和0~8列:
1,1,1,1,1,1,1,1,1
1,0,0,1,0,0,1,0,1
1,0,0,1,1,0,0,0,1
1,0,1,0,1,1,0,1,1
1,0,0,0,0,1,0,0,1
1,1,0,1,0,1,0,0,1
1,1,0,1,0,1,0,0,1
1,1,0,1,0,0,0,0,1
1,1,1,1,1,1,1,1,10表示道路,1表示牆。
現在輸入一個道路的座標作為起點,再如輸入一個道路的座標作為終點,問最少走幾步才能從起點到達終點?
(注:一步是指從一座標點走到其上下左右相鄰座標點,如:從(3,1)到(4,1)。)
- 輸入
- 第一行輸入一個整數n(0<n<=100),表示有n組測試資料;
隨後n行,每行有四個整數a,b,c,d(0<=a,b,c,d<=8)分別表示起點的行、列,終點的行、列。 - 輸出
- 輸出最少走幾步。
- 樣例輸入
-
2 3 1 5 7 3 1 6 7
- 樣例輸出
-
12 11
初學DFS,想法很菜,勿噴。。。談一下解其他迷宮題的思路,有的題可能沒有設邊界(不像這道題周圍都是牆 封閉的),這時候會有bug,可能程式找的解不是在區域內的路線,可能會出這個區域,這時候要多加個限制條件,讓 0 < 座標 < 行數、列數;或是設定map地圖陣列時,在原有的區域周圍都加上一堵牆,用牆圈起來,這樣也能達到效果
DFS解法:
#include<cstdio> #include<algorithm> #define Q 10000 using namespace std; int x,y,ex,ey,ans; int dx[4]={-1,1,0,0}; int dy[4]={0,0,-1,1}; // dx[4],dy[4] 是為了控制 上下左右 四個方向的 int map[9][9]={ 1,1,1,1,1,1,1,1,1, 1,0,0,1,0,0,1,0,1, 1,0,0,1,1,0,0,0,1, 1,0,1,0,1,1,0,1,1, 1,0,0,0,0,1,0,0,1, 1,1,0,1,0,1,0,0,1, 1,1,0,1,0,1,0,0,1, 1,1,0,1,0,0,0,0,1, 1,1,1,1,1,1,1,1,1 }; void DFS(int x,int y,int c) //找到滿足條件的最優解 { if(x==ex&&y==ey) { if(c<ans) // 判斷此時的 c 是否為最優解 { ans=c; } } else { for(int i=0;i<4;i++) { int nx=x+dx[i]; int ny=y+dy[i]; if(!map[nx][ny]&&c<ans-1) // 限制此時的 c 比上一步的解 ans-1小 { map[nx][ny]=1; DFS(nx,ny,c+1); // 這裡 c 還要加 1,這就可以解釋上面判斷要 a<ans-1 了 map[nx][ny]=0; // 因為可能選擇一條路不通時,為下一條路的選擇,初始化該點 } } } } int main() { int t; scanf("%d",&t); while(t--) { int c=0; scanf("%d %d %d %d",&x,&y,&ex,&ey); ans=Q; // 這裡先給 ans 一個較大的值,要篩選 c map[x][y]=1; DFS(x,y,c); printf("%d\n",ans); map[x][y]=0; // 為了不影響下一組資料的測試,初始化該點 } return 0; }
BFS解法:
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<queue>
using namespace std;
int dx[4]={-1,1,0,0};
int dy[4]={0,0,-1,1};
int map[9][9]={ 1,1,1,1,1,1,1,1,1,
1,0,0,1,0,0,1,0,1,
1,0,0,1,1,0,0,0,1,
1,0,1,0,1,1,0,1,1,
1,0,0,0,0,1,0,0,1,
1,1,0,1,0,1,0,0,1,
1,1,0,1,0,1,0,0,1,
1,1,0,1,0,0,0,0,1,
1,1,1,1,1,1,1,1,1 };
bool vis[9][9];
int kx,ky,ex,ey;
struct node
{
int x,y,step;
};
int BFS()
{
node s;
s.x=kx, s.y=ky, s.step=0;
vis[kx][ky]=1;
queue<node> qu;
qu.push(s);
while( !qu.empty() )
{
node now=qu.front();
qu.pop();
if(now.x==ex&&now.y==ey)
return now.step;
for(int i=0;i<4;i++)
{
node next;
next.x=now.x+dx[i];
next.y=now.y+dy[i];
next.step=now.step;
if(!vis[next.x][next.y]&&!map[next.x][next.y])
{
vis[next.x][next.y]=1;
next.step+=1;
qu.push(next);
}
}
}
}
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
memset(vis,0,sizeof(vis));
scanf("%d %d %d %d",&kx,&ky,&ex,&ey);
printf("%d\n",BFS());
}
return 0;
}