所谓DFS,即深度优先搜索,通过遍历所有可能来找出答案,所以可以看作一种暴力求解法,所以他的时间复杂度较高,一般数据大一点就不太适用,可以考虑BFS(广度优先搜索)。

我们先将迷宫抽象成一个二维数组,如题所述,将所有能走的点标记为1,所有障碍标记为0,同时我们还应当考虑地图边界的问题,通过if的判断将搜索限制在地图的范围内

首先先定义出一个二维数组来记录地图信息,为了防止数据过多,数组应当尽量开大,并用两层for循环来输入地图信息:

int nex[100][100];
for (int i = 0; i < m; i++) {//n和m为题目所给行列数信息
		for (int j = 0; j < n; j++) {
			cin >> nex[i][j];
		}
	}

之后,我发现答案是将所有可能路径进行输出,但该地图为二维数组,所以我想到了用pair来存储每个坐标,之后的输出将轻松一点,pair的定义如下(www.cplusplus.com):

template <class T1, class T2> struct pair;

其中的template即模板,属于泛型编程。

下面我们定义一个pair数组:,用来存储可能的横纵坐标:

pair<int,int> q;

准备工作完成后,我们就要来实现DFS的核心代码了,所谓DFS,即是一种回溯的方法,属于一条路走到黑,不撞南墙不回头的暴力解法,回溯即是在一条路遍历完后,回到上一步的状态,继续为探索的道路,所以它的时间复杂度较高

void DFS(int x, int y, int step) {
	v_nex[sta_x - 1][sta_y - 1] = 1;
	if (x == p - 1 && y == q - 1) {
		num++;
		cout << "(" << sta_x << ',' << sta_y << ")" << "->";
		for (int j = 0; j < step; j++) {
			cout << "(" << ans[j].first << ',' << ans[j].second << ")";
			if (j != step - 1) {
				cout << "->";
			}
		}
		cout << endl;
		return;
	}
  
	//左
	if (nex[x][y - 1] == 1 && v_nex[x][y - 1] == 0) {
		v_nex[x][y - 1] = 1;
		ans[i++] = make_pair(x + 1, y);
		DFS(x, y - 1, step + 1);
		ans[i--] = make_pair(0, 0);
		v_nex[x][y - 1] = 0;
	}
  
	//上
	if (nex[x - 1][y] == 1 && v_nex[x - 1][y] == 0) {
		v_nex[x - 1][y] = 1;
		ans[i++] = make_pair(x, y + 1);
		DFS(x - 1, y, step + 1);
		ans[i--] = make_pair(0, 0);
		v_nex[x - 1][y] = 0;
	}
  
	//右
	if (nex[x][y + 1] == 1 && v_nex[x][y + 1] == 0) {
		v_nex[x][y + 1] = 1;
		ans[i++] = make_pair(x + 1, y + 2);
		DFS(x, y + 1, step + 1);
		ans[i--] = make_pair(0, 0);
		v_nex[x][y + 1] = 0;
	}
  
	//下
	if (nex[x + 1][y] == 1 && v_nex[x + 1][y] == 0) {
		v_nex[x + 1][y] = 1;
		ans[i++] = make_pair(x + 2, y + 1);
		DFS(x + 1, y, step + 1);
		ans[i--] = make_pair(0, 0);
		v_nex[x + 1][y] = 0;
	}
  
	return;
}

这里我用了函数来实现,方便后续的回溯,可以看到这段代码很长,但其实很没有必要,我因为是第一次写有关DFS的代码,为了后续更好的理解,我将左上右下分别用if来实现,其实完全可以优化精简,奈何初学者能力有限。

接下来我将分别解释一下上述代码:首先是一个if判断,用以当找到答案时回到上一个DFS函数调用(即回溯),并进行答案的输出。接下来就是冗长的递归代码,大致思想即对每个可能成为答案的节点进行深度搜索,直到搜索到头或是找到答案,最后的return即是进行回溯,返回上一次的调用。

//左
if (nex[x][y - 1] == 1 && v_nex[x][y - 1] == 0) {
	v_nex[x][y - 1] = 1;
	ans[i++] = make_pair(x + 1, y);
	DFS(x, y - 1, step + 1);
	ans[i--] = make_pair(0, 0);
	v_nex[x][y - 1] = 0;
}

之后我截取其中一段来解释其工作原理:首先是对下一步将要走的节点的合理性进行判断,比如是否超过地图边界,是否已经遍历过等等,如果下一节点合理,则首先对其进行标记,表示其已经被遍历了,用ans来存储该节点的坐标,调用了make_pair函数来对pair类型的数据进行赋值,随后对下一节点进行递归,对下一节点执行相同操作,直到找到答案或遍历到头。

等到函数回溯时,对该节点的标记置零,表示该点遍历结束,可以继续访问,并将此前记录的答案置零。

答案要求我们输出所有遍历节点,所以我又定义了一个变量num来存储节点的个数,当完成所有遍历后,如果num还是等于0,则证明没有满足条件的答案,故输出-1。

完整代码如下:

//DFS(深度优先搜索)
#include<iostream>
#include<vector>
using namespace std;

int n_min = (int)1e5;
pair<int, int> ans[100];
int nex[100][100];
int v_nex[100][100];
int i = 0;
int m, n;
int p, q;
int num = 0;
int sta_x, sta_y;
void DFS(int x, int y, int step) {
	v_nex[sta_x - 1][sta_y - 1] = 1;
	if (x == p - 1 && y == q - 1) {
		num++;
		cout << "(" << sta_x << ',' << sta_y << ")" << "->";
		for (int j = 0; j < step; j++) {
			cout << "(" << ans[j].first << ',' << ans[j].second << ")";
			if (j != step - 1) {
				cout << "->";
			}
		}
		cout << endl;
		return;
	}
	//左

	if (nex[x][y - 1] == 1 && v_nex[x][y - 1] == 0) {
		v_nex[x][y - 1] = 1;
		ans[i++] = make_pair(x + 1, y);
		DFS(x, y - 1, step + 1);
		ans[i--] = make_pair(0, 0);

		v_nex[x][y - 1] = 0;
	}
	//上

	if (nex[x - 1][y] == 1 && v_nex[x - 1][y] == 0) {
		v_nex[x - 1][y] = 1;
		ans[i++] = make_pair(x, y + 1);
		DFS(x - 1, y, step + 1);
		ans[i--] = make_pair(0, 0);
		v_nex[x - 1][y] = 0;
	}
	//右

	if (nex[x][y + 1] == 1 && v_nex[x][y + 1] == 0) {
		v_nex[x][y + 1] = 1;
		ans[i++] = make_pair(x + 1, y + 2);
		DFS(x, y + 1, step + 1);
		ans[i--] = make_pair(0, 0);

		v_nex[x][y + 1] = 0;
	}
	//下
	if (nex[x + 1][y] == 1 && v_nex[x + 1][y] == 0) {
		v_nex[x + 1][y] = 1;
		ans[i++] = make_pair(x + 2, y + 1);
		DFS(x + 1, y, step + 1);
		ans[i--] = make_pair(0, 0);

		v_nex[x + 1][y] = 0;
	}
	return;
}

int main(void) {
	cin >> m >> n;

	for (int i = 0; i < m; i++) {
		for (int j = 0; j < n; j++) {
			cin >> nex[i][j];
		}
	}
	cin >> sta_x >> sta_y;
	cin >> p >> q;
	DFS(sta_x - 1, sta_y - 1, 0);
	if (num == 0) {
		cout << -1;
	}
	return 0;
}