美文网首页编程C/C++天花板编程手把手
天花板编程手把手计划-第1期-第3天

天花板编程手把手计划-第1期-第3天

作者: 天花板 | 来源:发表于2017-04-24 15:08 被阅读1290次

    上一篇的迷宫问题难倒了很多人,对于初学者这个相对综合的问题可能的确有点难,不过并非完成不了。我们今天就来看看初学者如何用最基础的方法解决这个问题。

    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
    

    我是天花板,让我们一起在软件开发中自我迭代。
    如有任何问题,欢迎与我联系。


    上一篇:天花板编程手把手计划-第1期-第2天

    相关文章

      网友评论

      • 4644f2f5191a:http://www.jianshu.com/p/e210c2a17264
        天花板:看看这段代码,评论里不能使用代码框,你复制出来看吧
        天花板:代码写的不错,不过算法还可以优化。

        #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);
        }
      • 老哥很稳:http://www.jianshu.com/p/3bea90b3cdec
        老哥很稳:用递归的方法又从新做了一遍,还是使用的二进制,现在还想不出新的方法来做,只是把第一个for循环简单的改成了一个递归函数,和楼上的差不多。关于变量的命名,之前的视频教程里也经常强调这个,但到自己写的时候总是想不出起什么名字,自己需要学的东西还很多。
        天花板:用二进制的方法的确是偷懒了,不过这个懒也偷的不够好,可以参考一下楼上的偷懒方法。循环的次数还可以更少。另外,变量命名太随意也不好。
        看懂楼上的代码后再思考一下用递归的方法怎么解决。
      • Hans941:http://www.jianshu.com/p/61a42cf28151
        天花板:再说说你的硬币算法。这个思路很好,利用了二进制来完成。既然完全转化成了二进制的问题,给你分享另一种输出方式。我重写了你的binary函数。
        void binary(int number)
        {
        char str[10];
        _itoa(number, str, 2);
        printf("%06s\n", str);
        }
        天花板:@Aha_斌 还用一个办法是在设计二维数组的时候定义一个8*8的二维数组。把题目中的数据保存在中间6*6的空间里,最外层的一圈空格填1。
        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空间里的)时就不用担心越界了,因为最外层没有可以走的位置。这是这类问题的经典方法,后面我们将其它解法时也会用到。
        Hans941: @Aha_斌
        1.迷宫里的矩形不属于支路,会绕路
        2.在cutBranch函数中检查的点是点A周围的四个点,并不检查点A本身。所以在遍历时只需要遍历中间的各个点而不用遍历迷宫周围的一圈点。这样就刚好解决了越界问题,而不用再进行多余的越界判断了。

      本文标题:天花板编程手把手计划-第1期-第3天

      本文链接:https://www.haomeiwen.com/subject/yolpzttx.html