搜尋與回溯 1215:迷宮
阿新 • • 發佈:2018-12-11
【題目描述】
一天Extense在森林裡探險的時候不小心走入了一個迷宮,迷宮可以看成是由n * n的格點組成,每個格點只有2種狀態,.和#,前者表示可以通行後者表示不能通行。同時當Extense處在某個格點時,他只能移動到東南西北(或者說上下左右)四個方向之一的相鄰格點上,Extense想要從點A走到點B,問在不走出迷宮的情況下能不能辦到。如果起點或者終點有一個不能通行(為#),則看成無法辦到。
【輸入】
第1行是測試資料的組數k,後面跟著k組輸入。每組測試資料的第1行是一個正整數n (1 ≤ n ≤ 100),表示迷宮的規模是n * n的。接下來是一個n * n的矩陣,矩陣中的元素為.或者#。再接下來一行是4個整數ha, la, hb, lb,描述A處在第ha行, 第la列,B處在第hb行, 第lb列。注意到ha, la, hb, lb全部是從0開始計數的。
【輸出】
k行,每行輸出對應一個輸入。能辦到則輸出“YES”,否則輸出“NO”。
【輸入樣例】
2 3 .## ..# #.. 0 0 2 2 5 ..... ###.# ..#.. ###.. ...#. 0 0 4 0
【輸出樣例】
YES NO
此題採用搜尋與回溯,考慮到超時問題而且只需要有一條路徑就可以了,所以不需要回溯,關於輸出,我用了一個flag檢查是否可以到達,剛開始我本來是用dfs的返回值來判斷是否可以到達,結果有問題,因為這樣的返回值是最後一條路徑是否可以到達。剛開始也沒有用到b陣列,後面發現這樣會無限迴圈,所以添加了一個b[i]陣列判斷該點是否走過!
#include<iostream> #include<cstdio> #include<cstring> #define maxn 100+5 using namespace std; int k,n,ha,la,hb,lb; char a[maxn][maxn]={}; int da[5]={0,1,0,-1}; int db[5]={1,0,-1,0}; bool b[maxn][maxn]={}; int flag=0; bool dfs(int x,int y) { if(x==hb&&y==lb) { flag=1; return true; } for(int i=0;i<4;i++) { int p=x+da[i]; int q=y+db[i]; if(a[p][q]=='.'&&b[p][q]==0&&p>=0&&q>=0&&p<n&&q<n) { b[p][q]=1; dfs(p,q); } } return false; } int main() { cin>>k; while(k!=0) { k--; cin>>n; flag=0; memset(a,0,sizeof(a)); memset(b,0,sizeof(b)); for(int i=0;i<n;i++) { for(int j=0;j<n;j++) { cin>>a[i][j]; } } cin>>ha>>la>>hb>>lb; if(a[ha][la]=='#'||a[hb][lb]=='#') { cout<<"NO"<<endl; continue; } b[ha][la]=1; dfs(ha,la); if(flag==1) cout<<"YES"<<endl; else cout<<"NO"<<endl; } return 0; }