1. 程式人生 > >搜尋與回溯 1215:迷宮

搜尋與回溯 1215:迷宮

【題目描述】

一天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;
}