网易极客战记官网codecombat|编程解决算法问题「农民过河」,穷举思想轻松学(一)
用极客战记学习编程,孩子学习的并非只有代码。
很多关卡在向孩子教学代码的同时,更是在潜移默化地训练孩子的编程思维。
在最开始的地牢地图中,孩子需要使用「While-True」循环语句,穿过一个又一个结构重复的迷宫。
在学习「While-True」循环语句的同时,也在训练着使用「循环思维」解决重复问题的能力:
- 发现并拆解重复部分
- 解决重复问题
- 循环运行问题的解决方法
这样,就能只用一段代码,高效地解决重复问题了。
可见,在编程中,学习代码的编写只是基本,更重要的还是掌握运用代码的编程思维。
农民过河问题
在编程的数道经典算法问题中,有一个「农夫过河」问题:
一个农夫带着一只狼,一只羊和一些菜过河。河边只有一条船,由于船太小,只能装下农夫和他的一样东西,在无人看管的情况下,狼要吃羊,羊要吃菜,请问农夫如何才能使三样东西平安过河。
为了用代码解决这个问题,程序员需要利用**「穷举搜索思想」,尝试所有的过河方案,直到找出正确的过河方案。**
而在极客战记中,也有着类似的一关。
「士兵,食人魔和农民」
关卡地址:
https://codecombat.163.com/play/level/soldier-ogre-and-peasant?
关卡介绍:
你需要使用狮鹫,把士兵、食人魔、农民,带去河的对岸,狮鹫每次只能带一个人离开,而食人魔会伤害农民,士兵会攻击食人魔,因此不要让士兵和食人魔单独留在一起,也不要让食人魔和农民单独留在一起。
这一关是和「农夫过河」同类型的问题,就像一个脑筋急转弯,不用代码,用我们的智慧,动动脑筋,应该很快就能想出解法。
但你能想出一种解法,如果你想找出所有的解法,是不是就有一定的难度了呢?如何更快更全地找出所有的过河方法呢?
在本关,我们可以学习一下如何使用「穷举思想」解决编程问题。
穷举是什么?
穷举是什么呢?它有着一个高大上的名字,但它的本质却十分的简单朴实。
穷举法的基本思想:根据题目的部分条件确定答案的大致范围,并在此范围内对所有可能的情况逐一验证,直到全部情况验证完毕。
简单来说就是:把所有的答案都试一遍,找出正确的答案。
非常的简单粗暴。
因此,它也是编程常用中效率较低的一种算法。
使用穷举法,通常需要三步:解析题目——优化运算过程——开始穷举。
我们来试试利用穷举法解决关卡「士兵,食人魔和农民」吧!
第一步:解析题目
穷举法的第一步就是分析题目,把原本的文字题目,转化成更易于分析,简洁有逻辑的题目类型。
① 题目的对象
题目看似只是三个人的过河问题,但实际上在题目里有四个人物:狮鹫、士兵、食人魔、农民。狮鹫负责帮助大家过河。
② 题目的条件
一、士兵和食人魔不能单独留在一起;
二、食人魔和农民也不能单独留在一起。
也就是说,当狮鹫、士兵、食人魔呆在一起的时候,也不会发生问题,因为士兵和食人魔马上就要被狮鹫运走,来不及打架。
③ 题目的状态
我们需要使用狮鹫来帮助他们从右边飞到左边,因此题目具有以下几种可能发生的情况:
左边有士兵、食人魔、农民、狮鹫,右边什么都没有。
左边有食人魔、农民、狮鹫,右边有士兵。
左边有农民、狮鹫,右边有士兵、食人魔。
……等等多种情况
④ 优雅地表示题目
可以看到,**用文字标识题目可能发生的情况,十分地复杂。**因此,在编程中,我们常常会用一些特定的符号来简洁地表达题目可能发生的情况。
看看题目,人物只会有两种状态,在右边(还没过河),在左边(过河了),因此我们可以直接用0、1来表示人物的位置。
0表示还没过河;1表示已经过河。
那么就可以这样表示:(狮鹫、士兵、食人魔、农民)
- (1,1,1,1)表示所有人物都已过河,到了左边。
- (1,0,1,1)表示食人魔和农民过了河,士兵还没有。
- ……等等
用这种简洁的方式,把题目的所有情况表示出来就是:
共16种状态。
根据题目的条件,我们可知,有以下几种情况是不可取的:
农民和食人魔单独在一起:(0,0,1,1)、(1,1,0,0)
士兵和食人魔单独在一起:(0,1,1,0)、(1,0,0,1)
还有两种隐含的不可取条件:
只有狮鹫自己在一边:(1,0,0,0),这表示,所有人都没过河,只有狮鹫过河了,而狮鹫本来就是帮助大家过河的,不可能自己单独呆在河的一边。所以这种情况是不会发生的。
那么同理还有:(0,1,1,1)这种情况,所有人都过了河,狮鹫没有过河,这也不会发生。
那么本题的问题就变成了:
如何在符合条件的情况下,把(0,0,0,0)转化成(1,1,1,1)。
把题目转化成一个易于分析的题目类型,这才是穷举法的开始。
而穷举法的魅力,还不在这里**,它能够帮助我们更快更全地找出问题的所有结果**,究竟我们要如何对这个题目进行穷举呢?
编程解决算法问题「农民过河」,穷举思想轻松学(二)将会为你揭秘!