You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

205 lines
3.9 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

#include <bits/stdc++.h>
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<Node> path;
//全部路径,都记录下来
vector<vector<Node> > 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<Node> 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<Node> x, vector<Node> 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....
*/