[C++] DFS-迷宫问题全部路径

文章目录

  • 1.题目
  • 2.
    • 2.1. 存储
    • 2.2.读取模块:
    • 2.3.输出模块
  • 3.DFS
  • 4.完整代码

1.题目

描述:
给定一个 m ∗ n m*n mn的迷宫,从 S S S出发,到 T T T,找出它的所有答案
样例输入:

5 6
....S#
.##...
.#..#.
#..##.
.T....

样例输出:

The best answer is:
...++#
.##+..
.#++#.
#.+##.
.++...
step = 7

The other answers are:
...++#
.##+..
.#++#.
#.+##.
.++...
step = 7

....+#
.##++.
.#++#.
#++##.
.+....
step = 7

....+#
.##++.
.#++#.
#.+##.
.++...
step = 7

....+#
.##.++
.#..#+
#..##+
.+++++
step = 9

...++#
.##+++
.#..#+
#..##+
.+++++
step = 11

....+#
.##.++
.#..#+
#++##+
.+++++
step = 11

...++#
.##+++
.#..#+
#++##+
.+++++
step = 13

sum = 8

2.

2.1. 存储

bool型存就可以了:

bool map[SIZE][SIZE];

( 1 , 1 ) (1, 1) (1,1) ( m , n ) (m, n) (m,n) ,用false做墙,true做空地。
这样,由于全局变量默认为false,自然地图边缘就有了一圈墙

              ########
....S#        #....S##
.##...        #.##...#
.#..#.  --->  #.#..#.#
#..##.        ##..##.#
.T....        #.T....#
              ########

考虑到要图形化输出,先存一份原图:

char pic[SIZE][SIZE];

路径用vector存一下:

struct Move {
	int x, y;
	Move(int a, int b) {
		x = a;y = b;
	}
};

vector<Move> path;
vector<vector<Move> > allpath;

2.2.读取模块:

scanf("%d %d", &m, &n);
sx = 1; sy = 1; tx = m; ty = n;
	
for (int i = 0; i < m; ++i) {
	char s[SIZE];
	scanf("%s", pic[i]);
	strcpy(s, pic[i]);
	for (int j = 0; j < n; ++j) {
		char c = s[j];
		if (c == 'S') sx = i+1, sy = j+1, map[i+1][j+1] = 1;
		else if (c == 'T') tx = i+1, ty = j+1, map[i+1][j+1] = 1;
		else if (c == '#') map[i+1][j+1] = 0;
		else map[i+1][j+1] = 1;
	}
}

2.3.输出模块

void showpath(vector<Move> x) {
	char s[SIZE][SIZE];
	for (int i = 0; i < n; ++i) {
		strcpy(s[i], pic[i]);
	}
	for (int i = 0; i < x.size(); ++i) {
		s[x[i].x-1][x[i].y-1] = '+';
	}
	for (int i = 0; i < m; ++i) puts(s[i]);
	printf("step = %d\n", x.size()-1);
	printf("\n");
}
dfs(sx , sy);
if (allpath.size() == 0) {
	printf("No Answer.\n");
} else {
	sort(allpath.begin(), allpath.end(), cmp);
	printf("The best answer is:\n");
	showpath(allpath[0]);
	
	printf("The other answers are:\n");
	for (int i = 1; i < allpath.size(); ++i) {
  		showpath(allpath[i]);
	}
	printf("sum = %d\n", allpath.size());
}

3.DFS

终于开始写核心代码了。
先看代码:

void dfs(int x, int y) {
	if (x == tx && y == ty) { //1
		path.push_back(Move(x, y));
		allpath.push_back(path);
		path.pop_back();
		return;
	}
	//2
	if (!map[x][y]) return;
	if (visit[x][y]) return;
	path.push_back(Move(x, y));
	visit[x][y] = 1;
	for (int i = 0; i < 4; ++i) { //3
		int xx = x + d[i][0], yy = y + d[i][1];
		dfs(xx, yy);
	}
	//4
	visit[x][y] = 0;
	path.pop_back();
	return ;
}

1. 1. 1. 如果到达终点后:

  1. 保存路径
  2. 退出最后移动

2. 2. 2.判断此步合法性

  1. 是墙壁?
  2. 已经来过?

3. 3. 3.探索
4. 4. 4.恢复状态

4.完整代码

#include 
#include 
#include 
#include 
#include 
#define SIZE 100
using namespace std;

struct Move {
	int x, y;
	Move(int a, int b) {
		x = a;y = b;
	}
};

bool map[SIZE][SIZE], visit[SIZE][SIZE];
int m, n, sx, sy, tx, ty;
const int d[][2] = {{0, -1}, {-1, 0}, {1, 0}, {0, 1}};
vector<Move> path;
vector<vector<Move> > allpath;
char pic[SIZE][SIZE];

void dfs(int x, int y) {
	if (x == tx && y == ty) {
		path.push_back(Move(x, y));
		allpath.push_back(path);
		path.pop_back();
		return ;
	}
	
	if (!map[x][y]) return ;
	if (visit[x][y]) return ;
	path.push_back(Move(x, y));
	visit[x][y] = 1;
	for (int i = 0; i < 4; ++i) {
		int xx = x + d[i][0], yy = y + d[i][1];
		dfs(xx, yy);
	}
	visit[x][y] = 0;
	path.pop_back();
	return ;
}

void showpath(vector<Move> x) {
	char s[SIZE][SIZE];
	for (int i = 0; i < n; ++i) {
		strcpy(s[i], pic[i]);
	}
	for (int i = 0; i < x.size(); ++i) {
		s[x[i].x-1][x[i].y-1] = '+';
	}
	for (int i = 0; i < m; ++i) puts(s[i]);
	printf("step = %d\n", x.size()-1);
	printf("\n");
}

bool cmp(vector<Move> x, vector<Move> y) {
	return x.size() < y.size();
}

int main() {
	scanf("%d %d", &m, &n);
	sx = 1; sy = 1; tx = m; ty = n;
	
	for (int i = 0; i < m; ++i) {
		char s[SIZE];
		scanf("%s", pic[i]);
		strcpy(s, pic[i]);
		for (int j = 0; j < n; ++j) {
			char c = s[j];
			if (c == 'S') sx = i+1, sy = j+1, map[i+1][j+1] = 1;
			else if (c == 'T') tx = i+1, ty = j+1, map[i+1][j+1] = 1;
			else if (c == '#') map[i+1][j+1] = 0;
			else map[i+1][j+1] = 1;
		}
	}

	dfs(sx , sy);
	if (allpath.size() == 0) {
		printf("No Answer.\n");
	} else {
		sort(allpath.begin(), allpath.end(), cmp);
		printf("The best answer is:\n");
		showpath(allpath[0]);
		
		printf("The other answers are:\n");
		for (int i = 1; i < allpath.size(); ++i) {
  			showpath(allpath[i]);
		}
		printf("sum = %d\n", allpath.size());
	}
	return 0;
}

/*
副两个样例:
4 4
S.##
..##
#..#
##.T

5 6
....S#
.##...
.#..#.
#..##.
.T....
*/

你可能感兴趣的:(算法,计蒜客)