page contents

python基础编程100例:第50期-八人过河

本文讲述了python基础编程100例:第50期-八人过河!具有很好的参考价值,希望对大家有所帮助。一起跟随六星小编过来看看吧,具体如下:

attachments-2022-03-Bml83zDH623a7691b1c51.png

本文讲述了python基础编程100例:第50期-八人过河!具有很好的参考价值,希望对大家有所帮助。一起跟随六星小编过来看看吧,具体如下:

第50期-八人过河

1 问题描述

现在有8个人分别为:1个父亲,带着他的2个儿子。1个母亲,带着她的2个女儿;1个警察,带着1个犯人; 开始时,8个人都是在河的左岸。现在需要过河,过河时需要注意下面5条说明:

1,只有警察、父亲和母亲可以划船;

2,警察如果离开犯人,犯人就会伤害其他人;

3,母亲不在时,这个父亲会伤害她的女儿。

4,父亲不在时,这个母亲也会伤害他的儿子;

5,船上一次最多只能坐两个人。

试用python求出过河方案。


2 解题思路

第一步: 首先需要创建函数排除所有不能出现的情况

第二步: 遍历所有过河的可能

第三步: 通过第一步与第二部结合排除大部分情况

第四步: 可能会出现两个人往返过河无限循环的情况,需要排除这种情况


3 解题方法

left,ship,right,ship2=['警察','犯人','父亲','儿子','儿子','母亲','女儿','女儿'],[],[],[]

i=j=t=0


def rules(left1,right1,ship1):

    x=[left1,right1,ship1]

    for i in x:

        if ('父亲' not in i) and ('母亲' in i) and ('儿子' in i) :

            assert False

        if ('母亲' not in i) and ('父亲' in i) and ('女儿' in i) :

            assert False

        if ('警察' not in i) and ('犯人' in i) and (len(i)!=1):

            assert False

        if (i==ship1):

            if '父亲' not in i and '母亲' not in i and '警察' not in i:

                assert False


def actions_1(ship1,right1,left1):

    global ship,right,left,i,j,ship2

    while True:

            left1=left[:]

            ship1=ship[:]

            right1=right[:]

            ship1.append(left1.pop(i))

            ship1.append(left1.pop(j))

            for k in ship1:

                right1.append(k)

            try:

                rules(left1,right1,ship1)

                if sorted(ship1)==sorted(ship2):

                    assert False

                break

            except:

                j=j+1

                if j>len(left1):

                    i=i+1

                    j=i

                if i == len(left1)+1:

                    break

    ship2=ship1

    ship=[]

    right=right1

    left=left1

    i=j=0


def actions_2(ship1,right1,left1):

    global ship,right,left,i,j,t,ship2

    while True:

            left1=left[:]

            ship1=ship[:]

            right1=right[:]

            ship1.append(right1.pop(t))

            for k in ship1:

                left1.append(k)

            try:

                rules(left1,right1,ship1)

                break

            except:

                t=t+1

                if t == len(right1)+1:

                    left1=left[:]

                    ship1=ship[:]

                    right1=right[:]

                    break

    if ship1==[]:

        while True:

            left1=left[:]

            ship1=ship[:]

            right1=right[:]

            ship1.append(right1.pop(i))

            ship1.append(right1.pop(j))

            for k in ship1:

                left1.append(k)

            try:

                rules(left1,right1,ship1)

                break

            except:

                j=j+1

                if j>len(right1):

                    i=i+1

                    j=i

                if i == len(right1)+1:

                    break

    ship2=ship1

    ship=[]

    right=right1

    left=left1

    i=j=t=0

while True:

    actions_1(ship,right,left)

    print(f'{ship2}从左往右')

    print(f'此时左边剩下{left},右边剩下{right}')

    actions_2(ship,right,left)

    print(f'{ship2}从右往左')

    print(f'此时左边剩下{left},右边剩下{right}')

    if len(left)==2:

        actions_1(ship,right,left)

        print(f'{ship2}从左往右')

        print(f'此时左边剩下{left},右边剩下{right}')

        break

第1行: 定义列表left、ship、right、ship2并分别添加元素(ship与ship2用来判断是否出现重复循环)

第2行: 定义变量i、j、k用来判断何时结束循环

第5行: 定义规则函数rules并引入自变量left1,right1,ship1

第6行: 为left1,right1,ship1创建列表x

第7-16行: 根据题意创建规则,若违反规则则报错,用于与后面try、except语句相互配合

第18-19行: 创建函数actions_1并引入全局变量ship,right,left,i,j,ship2,代表船从左到右

第20行: 无限循环直到不触碰规则

第21-23行: 复制列表left、ship、right到left1,right1,ship1中

第24-25行: 从左边(left1列表中)选出两个元素移到ship1中

第26-27行: 使用for循环遍历ship1中的元素移到右边(right1列表中)(不删除船中的元素,用以判断本次运行过程是否触发规则)

第28-29行: 判断左岸、船上、右岸的人员是否都会安全,不安全则报错

第30-31行: 判断从右到左的船上和从左到右的船上两人是一样的,若是一样的会陷入循环,报错

第32行: 若都不报错,则行动正确,结束循环

第33行: 若try中报错,则运行此处

第34-37行: 索引i、j进行变化以便下次索引

第38-39行: 超出列表则结束循环(若代码正确这段可以不要)

第40-41行: ship2记住本次行动人员以便下次判断是否重复,ship船清零

第42-43行: 左右两岸记住本次剩余人员

第44行: i、j清零用于下次索引

第46-47行: 创建函数actions_2并引入全局变量ship,right,left,i,j,t,ship2,代表船从右到左

第48行: 无限循环直到不触碰规则

第49-51行: 复制列表left、ship、right到left1,right1,ship1中

第52行: 从右边(right1列表中)选出一个元素移到ship1中(优先选出一个,用于求解)

第53-54行: 使用for循环遍历ship1中的元素移到左边(left1列表中)(不删除船中的元素,用以判断本次运行过程是否触发规则)

第55-56行: 判断左岸、船上、右岸的人员是否都会安全,不安全则报错

第57行: 结束循环(这里一个人和两个人不可能重复,不用判断是否与上次船相等)

第58行: 若try中报错,则运行此处

第59行: 索引t进行变化以便下次索引

第60-64行: 超出列表则结束循环并给left1,right1,ship1重新复制

第65-88行: 参考20-44行,代码基本相同,表示从右边运输两个人到左边

第89行: 无限循环直到运输完毕

第90-95行: 引用左右船两个函数并输出左岸的人数,以及船上的人

第96-100行: 由于最后一段是从左岸到右岸,判断左岸人数是否为2,是则进行最后一次运输并结束循环


代码运行结果为:

attachments-2022-03-ok7xXPXx623a762f8b3a4.png


小思考1

为什么65-88行中不用判断是否与前面过来的船重复呢?

小思考2

代码中有哪些是可以删除的嘛?

更多相关技术内容咨询欢迎前往并持续关注六星社区了解详情。

想高效系统的学习Python编程语言,推荐大家关注一个微信公众号:Python编程学习圈。每天分享行业资讯、技术干货供大家阅读,关注即可免费领取整套Python入门到进阶的学习资料以及教程,感兴趣的小伙伴赶紧行动起来吧。

attachments-2022-05-v0eLmCKZ629092a514605.jpeg

  • 发表于 2022-03-23 09:24
  • 阅读 ( 751 )
  • 分类:Python开发

0 条评论

请先 登录 后评论
轩辕小不懂
轩辕小不懂

2403 篇文章

作家榜 »

  1. 轩辕小不懂 2403 文章
  2. 小柒 1474 文章
  3. Pack 1135 文章
  4. Nen 576 文章
  5. 王昭君 209 文章
  6. 文双 71 文章
  7. 小威 64 文章
  8. Cara 36 文章