网易极客战记官网codecombat|编程解决算法问题「农民过河」,穷举思想轻松学(二)
用极客战记学习编程,孩子学习的并非只有代码。
当我们遇到如「农夫过河」之类像脑筋急转弯的算法题,我们动动脑子,或许很快就能直接想出一种解法。
但如果我们想找出所有的解法,是不是就有一定的难度了呢?如何更快更全地找出所有的过河方法呢?
因此,我们需要学会一种更有条理更系统化的处理算法:「穷举法」
在上一节课里,我们已经对题目进行了分析解析,把一个深奥复杂的文字题,通过一系列的转化,变成了一个简单易懂,更适合电脑处理的数字题目。
第二步:优化运算过程
根据上方的分析,我们把问题转化成了在符合条件的情况下,把(0,0,0,0)转化成(1,1,1,1)。此时的题目已经变的简单易懂,接下来就要开始解决题目了。
穷举法的本质就是把所有的答案都尝试一遍,因此穷举法会有比较复杂的运算过程,例如:
第一次过河,狮鹫带士兵过河,结果是
(1,1,0,0)
第二次过河,狮鹫带食人魔过河,结果是
(1,1,1,0)
由于过河必须要狮鹫的帮助,因此,每次过河完的结果,狮鹫一定是与过河人在同一个位置上的。
所以,我们能够得到四种表示过河方式的状态:
(1,0,0,0):狮鹫自己过河
(1,1,0,0):狮鹫带士兵过河
(1,0,1,0):狮鹫带食人魔过河
(1,0,0,1):狮鹫带农民过河
那么再看,如果我们要表示,第一次过河,狮鹫带食人魔过河,可以这样表示:
过河前(0,0,0,0);
过河方式:(1,0,1,0);
过河结果:(1,0,1,0);
第二次过河,狮鹫带士兵过河:
① 先让狮鹫飞回来:
过河前(1,0,1,0);
过河方式:(1,0,0,0);
过河结果:(0,0,1,0);
② 再让狮鹫带士兵过河:
过河前(0,0,1,0);
过河方式:(1,1,0,0);
过河结果:(1,1,1,0);
看看上面的三组过程,仔细观察。
你会发现,当0和1相遇,它的结果就会变成1,当1和1相遇,它的结果会变成0。
因此我们还可以把过河的情况,用更简洁的方式表示出来。
定义一个运算规则:0+1=1,1+1=0
因此,过河就可以这样表示:
(0,0,0,0)+(1,0,1,0)=(1,0,1,0)
(1,0,1,0)+(1,0,0,0)=(0,0,1,0)
然后,我们就可以开始穷举啦。
第三步:开始穷举
最初四个人物的状态为:(0,0,0,0)
四种过河方式为:
(1,0,0,0):狮鹫自己过河
(1,1,0,0):狮鹫带士兵过河
(1,0,1,0):狮鹫带食人魔过河
(1,0,0,1):狮鹫带农民过河
第一次过河:
第一次过河的运算式我们可以这么写:
看看最后得出的四个结果,我们拿题目的条件来检验一下。
第一个结果(1,0,0,0),只有狮鹫过河,这是没有意义的过河,所以这一结果不可取。
第二个结果(1,1,0,0),狮鹫带士兵过河,那么这样农民和食人魔就都是0,单独呆在了一块,农民就会受到食人魔的攻击,因此也是不行的。
第三个结果(1,0,1,0),狮鹫带食人魔过河,士兵和农民在一边,狮鹫和食人魔在一边,不会发生问题,这个结果可行。
第四个结果(1,0,0,1),狮鹫带农民过河,士兵和食人魔呆在了一块,这也不行。
因此可以得出,第一次过河的正确过河方式是:
(0,0,0,0)+(1,0,1,0)=(1,0,1,0)狮鹫带食人魔过河
第二次过河:
而第二次过河,需要先让狮鹫飞回右边,同样也是有四种过河方式:
第一步,先让狮鹫飞回右边,同样也是有四种过河方式:
但,此时这边只有食人魔和狮鹫,因此可取的过河方式仅有(1,0,0,0)和(1,0,1,0):
对结果进行分析,若是第二种方式,(0,0,0,0)等于又变回没过河前的状态了,不可取,因此结果为让狮鹫自己飞回去:(0,0,1,0)
第三次过河:
然后再拿上面的结果进行第三次过河的运算:
同样,再次分析,得出结果。
(1,0,1,0)等于又回到了上一步的状态,因此不可取;
(1,1,1,0)可行
(1,0,1,1)可行
每次都取可行的结果进行运算,直到算出(1,1,1,1),如此下去,就能利用穷举,把所有的过河方式给穷举出来啦。
穷举法的利弊
穷举法的思想就是如此,首先对题目和运算过程进行分析,让它能够以更具逻辑的方式表达出来,然后,算出所有的结果并检验是否可行。
虽然<农民过河>就像脑筋急转弯一样简单,但真要找出所有的解决方法,不用算法,直接思考,还是需要一定的时间。
而使用上更有逻辑的穷举法,**甚至无需太多的思考,跟着运算过程一步步算下去,机械化地就能得到所有的正确结果,**精准无误,手动计算都这么方便了,那么用电脑代码实现,只会更快更方便。
它的优点就在于,它是一个极其简单易懂的算法。就像解决<农夫过河>问题一样,我们可以十分轻松地把穷举法的思想带进我们的生活问题中使用。
而穷举的缺点十分明显:
穷举的方法很逻辑化,易于执行,但计算所有结果,就为了找出几个正确结果,操作量十分庞大,十分麻烦,如果题目变得更加复杂,那穷举就变得更不实用了。
在未来,你还会学到更多更强大的算法,与穷举法相比,它们还可以更智能地得到条件,把无用运算筛选掉,提高效率。
如果题目变得更为复杂,哪怕是电脑,穷举都需要非常久的工作时间,远远不如其他先进的算法。
事实上,无论哪种算法,都有利弊,都有比它先进的算法,可见,唯有不断地学习,掌握越来越多先进的知识,才是最先进的算法。
本攻略发于极客战记
极客战记——学编程,用玩的!