给定一迷宫,1代表障碍物,0代表可通节点,求一条从迷宫入口到迷宫出库的路径。
本算法设定迷宫大小为Y_MAX*X_MAX,入口为[1][1],出口为[Y_MAX-2][X_MAX-2]
在每个节点时依次按照下、右、上、左的顺序寻找下个节点能否通过。
具体实现见代码,下为实际运行效果图。
当迷宫存在通路时:
当迷宫不存在通路时:
//转载请标明出处 Postlude
#include <iostream>
#include <stack>
#include <iomanip>
using namespace std;
#define X_MAX 10
#define Y_MAX 10
int map[Y_MAX][X_MAX];
int flag = 0;
void get_map()
{
for (int i = 0; i < Y_MAX; i++)
for (int j = 0; j < X_MAX; j++)
cin >> map[i][j];
}
void print_map()
{
if (flag)
cout << "\n\n该迷宫存在通路! 且路径长度为:" << map[Y_MAX - 2][X_MAX - 2] << endl;
else
cout << "\n\n该迷宫不存在通路!\n";
cout << "\n可视化图形界面如下:\n1.★表示路径 2.☆表示未经过节点 3.□表示走过但走不通的节点 4.■表示障碍物\n";
for (int i = 0; i < Y_MAX; i++)
{
for (int j = 0; j < X_MAX; j++)
{
if (i == 1 && j == 1 && !flag)
{
cout << "□ ";
continue;
}
if (i == 1 && j == 1 && flag)
{
cout << "★ ";
continue;
}
if (map[i][j] == -1)
cout << "□ ";
else if (map[i][j] == 1)
cout << "■ ";
else if (map[i][j] == 0)
cout << "☆ ";
else
cout << "★ ";
}
cout << endl;
}
cout << "\n—————————————————————"<<endl;
for (int i = 0; i < Y_MAX; i++)
{
cout << "|";
for (int j = 0; j < X_MAX; j++)
{
cout << map[i][j] << setw(4);
}
cout << "|";
cout << endl;
}
cout << "—————————————————————" << endl<<endl;
}
/*
map1 有通路:
1 1 1 1 1 1 1 1 1 1
1 0 1 0 0 0 0 0 1 1
1 0 0 1 1 0 1 0 0 1
1 0 0 1 1 0 1 0 0 1
1 0 0 0 0 0 1 0 0 1
1 0 0 1 1 0 1 0 0 1
1 0 1 1 0 0 1 0 0 1
1 0 1 1 1 0 1 1 0 1
1 1 1 1 1 0 1 0 0 1
1 1 1 1 1 1 1 1 1 1
map2 无通路:
1 1 1 1 1 1 1 1 1 1
1 0 1 0 1 0 0 0 1 1
1 0 0 1 1 0 1 0 0 1
1 0 0 1 1 0 1 0 0 1
1 0 0 0 0 0 1 0 0 1
1 0 0 1 1 0 1 0 0 1
1 0 1 1 0 0 1 0 0 1
1 0 1 1 1 0 1 1 1 1
1 1 1 1 1 0 1 0 0 1
1 1 1 1 1 1 1 1 1 1
*/
class Pos
{
public:
// x和y的坐标
int x;
int y;
};
//放入栈当中的通道块元素
class Item
{
public:
Item(int a, int b);
bool if_pass();
void get_nextpos(int pos);
void sign(int steps);
Pos p; //记录位置
int next; //下一步该走的方向
/*
1代表向下,2代表向右,3代表向上,4代表向左
*/
};
Item::Item(int a, int b)
{
p.x = a;
p.y = b;
}
bool Item::if_pass()
{
if (!map[p.y][p.x])
return 1;
else
return 0;
}
void Item::get_nextpos(int pos)
{
switch (pos)
{
case 1:
p.y++;
break;
case 2:
p.x++;
break;
case 3:
p.y--;
break;
case 4:
p.x--;
break;
}
}
void Item::sign(int steps)
{
map[p.y][p.x] = steps;
}
int main()
{
stack<Item> Path;
Item now(1, 1);
int steps = 1;
cout << "\n当前设置迷宫大小上限: X-" << X_MAX - 2 << " Y-" << Y_MAX - 2 << endl;
cout << "请输入迷宫:(1代表障碍物 0代表通路)" << endl;
get_map();
do
{
if (now.if_pass())
{
map[now.p.y][now.p.x] = steps; //标记迷宫为当前走过的步数
Item t(now.p.x, now.p.y);
t.next = 1;
Path.push(t);
if (now.p.x == X_MAX - 2 && now.p.y == Y_MAX - 2)
{
flag = 1;
break;
}
now.get_nextpos(1); //先让now继续向下走
steps++;
}
else
{
if (!Path.empty())
{
Item t = Path.top();
Path.pop();
steps--; //退回上一步
while (t.next == 4 && !Path.empty())
{
t.sign(-1); //如果走不通的话就赋值-1 代表走过了
t = Path.top();
Path.pop();
steps--;
}
//如果还有未被测试过的路径的话
if (t.next < 4)
{
now.p.x = t.p.x;
now.p.y = t.p.y;
t.next++;
now.get_nextpos(t.next);
steps++;
Path.push(t);
}
}
else
break;
}
} while (!Path.empty());
print_map();
}