描述:
给定一个 m ∗ n m*n m∗n的迷宫,从 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
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;
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;
}
}
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());
}
终于开始写核心代码了。
先看代码:
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. 如果到达终点后:
2. 2. 2.判断此步合法性
3. 3. 3.探索
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....
*/