#include using namespace std; /** * 功能:声明一个结构体,用来描述移动的横坐标与纵坐标 * 作者:黄海 * 时间:2019-11-17 */ struct Node { int x, y; Node(int a, int b) { x = a; y = b; } }; //地图大小,一般大开一点方便存储 #define SIZE 100 //右 const int d[4][2] = { {-1, 0}, {0, -1}, {1, 0}, {0, 1}}; //抽像后的地图,Flase:不可以走,True:可以走。 bool _map[SIZE][SIZE]; //考虑到要图形化输出,先存一份原图: char pic[SIZE][SIZE]; //是不是访问过? bool visit[SIZE][SIZE]; //本轮走的路径 vector path; //全部路径,都记录下来 vector > allpath; //地图 m:行,n:列 int m, n; //S:出发点,T:终点 ,那么sx,sy就是出发点的坐标,tx,ty就是终点的坐标 int sx, sy, tx, ty; //深度优先搜索 void dfs(int x, int y) { //如果找到了终点T,那么x=tx,y=ty if (x == tx && y == ty) { //记录这个结点 path.push_back(Node(x, y)); //将路径记录下来 allpath.push_back(path); //退出准备下一次尝试,这次的任务不是找到就完事了,而是要把所有的可能都找到,然后对比找到最小和路径,所以,需要不停的回退! path.pop_back(); return; } if (!_map[x][y]) return; //不能走就不走 if (visit[x][y]) return; //走过了也不走 //记录走过了这个结点(路径) path.push_back(Node(x, y)); //标识走了这个结点 dfs(xx, yy); } visit[x][y] = 1; //四个方向进行尝试 for (int i = 0; i < 4; ++i) { int xx = x + d[i][0], yy = y + d[i][1]; //四个方向进行深度优先探索 //从纸箱中取回,表未没有走过 visit[x][y] = 0; path.pop_back(); return; } /** * 功能:输出路径 * 作者:黄海 * 时间:2019-11-17 * @param x */ void showpath(vector 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 x, vector y) { return x.size() < y.size(); } int main() { //读取m:行,n:列 scanf("%d %d", &m, &n); //所谓初始值,就意味着下面的代码中需要在地图中找到S和T,然后修改sx,sy,tx,ty四个值。 //迷宫入口: sx = 1; //初始值 sy = 1; //初始值 //迷宫出口: tx = m; //初始值 ty = n; //初始值 //按行读取数据,共m行 for (int i = 0; i < m; i++) { scanf("%s", pic[i]); //按行读入地图 char s[SIZE]; strcpy(s, pic[i]);//复制行地图数据到s中 //按列遍历 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] = true; }//终点 else if (c == 'T') { tx = i + 1; ty = j + 1; _map[i + 1][j + 1] = true; }//不能走 else if (c == '#') { _map[i + 1][j + 1] = false; } else//可以走 { _map[i + 1][j + 1] = true; }; } } //深度优先,核心算法 dfs(sx, sy); //如果没有找到方案 if (allpath.size() == 0) { printf("没有适用的方案。\n"); } else { //对数据进行排序,找出步骤最少的方案 sort(allpath.begin(), allpath.end(), cmp); //输出最佳方案 printf("最佳方案:\n"); showpath(allpath[0]); //输出其余方案 printf("其余方案:\n"); for (int i = 1; i < allpath.size(); ++i) { showpath(allpath[i]); } //输出方案数 printf("方案数 = %d\n", allpath.size()); } return 0; } /* https://blog.csdn.net/szdytom/article/details/87537876 -- 下面是测试用例 5 6 ....S# .##... .#..#. #..##. .T.... 副另外两个样例: 4 4 S.## ..## #..# ##.T 5 6 ....S# .##... .#..#. #..##. .T.... */