上一篇的迷宫问题难倒了很多人,对于初学者这个相对综合的问题可能的确有点难,不过并非完成不了。我们今天就来看看初学者如何用最基础的方法解决这个问题。
1. 题目
如图所示,有一个6 * 6的迷宫,左上角为入口,右下角为出口。图中0的位置可以走,1的位置不能走。请编程找出唯一的一条通过迷宫的路。
2. 分析
2.1 经典解法
这道题是一个C语言编程中的经典题目,网上的答案有很多。有人还真去查了,但结果有点崩溃,他们看到的是:回溯、递归、堆栈、迭代、DFS这些初学者根本没怎么听过的关键词。那些没有注释的例程也是怎么也看不懂。其实,就因为题目太过经典,所以才有各种五花八门的解法。
总结一下,主流的解法就两种:
- DFS 深度优先遍历法
通过递归的方式不断从入口寻找下一个可行的点,依次执行下去。一旦发现死路就退回到上一个点重新寻找新路线。
理论上遍历了所有可能的路线之后,正确的路线一定能够找到。
- BFS 广度优先遍历法
这个算法的特点是不需要递归,需要自己维护一个顺序表,之后通过循环同时寻找和当前点相连的每一个联通的点,直到找到出口。
这个算法的特点是不需要回退。
以上两种是数据结构中的经典算法,不过我们今天要讲的并非这两种。所以千万不要被吓到了。
2.2 功能分解
首先说一下,经典的编程问题,每个都有经典的解法。这些解法是很多人共同总结出来的可以解决一类问题的最优算法。然而,对于某一个具体的问题,这些算法并不一定是最优的或者说最简单的。
这道题就是这样。迷宫问题最大的难点就是它有很多岔路是走不通的。那我们想想,如果迷宫没有岔路你会做吗?
把一个硬币抛5次,打印出所有可能出现的情况。1表示正面,0表示背面。比如:
全正面
1 1 1 1 1
全背面
0 0 0 0 0
我是天花板,让我们一起在软件开发中自我迭代。
如有任何问题,欢迎与我联系。
网友评论
#define COIN_NUMBER 5
void binary(int number);
void main()
{
int i;
int count;
count = pow((double)2, COIN_NUMBER);//计算有多少种可能性
for (i = 0; i < count; i++)//遍历所有可能性的次数
{
binary(i);
}
getchar();
}
void binary(int number)
{
char str[10];
_itoa(number, str, 2);
printf("%06s\n", str);
}
看懂楼上的代码后再思考一下用递归的方法怎么解决。
void binary(int number)
{
char str[10];
_itoa(number, str, 2);
printf("%06s\n", str);
}
int maze[MAX_SIZE][MAX_SIZE] =
{
{ 1, 1, 1, 1, 1, 1, 1, 1 },
{ 1, 0, 1, 0, 1, 1, 1, 1 },
{ 1, 0, 1, 1, 1, 0, 1, 1 },
{ 1, 0, 0, 0, 0, 0, 0, 1 },
{ 1, 0, 1, 0, 0, 1, 0, 1 },
{ 1, 0, 1, 0, 0, 1, 0, 1 },
{ 1, 0, 1, 1, 1, 1, 0, 1 },
{ 1, 1, 1, 1, 1, 1, 1, 1 }
};
这样判断有效数据(6*6空间里的)时就不用担心越界了,因为最外层没有可以走的位置。这是这类问题的经典方法,后面我们将其它解法时也会用到。
1.迷宫里的矩形不属于支路,会绕路
2.在cutBranch函数中检查的点是点A周围的四个点,并不检查点A本身。所以在遍历时只需要遍历中间的各个点而不用遍历迷宫周围的一圈点。这样就刚好解决了越界问题,而不用再进行多余的越界判断了。