Python_96 2022-12-26 14:55 采纳率: 50%
浏览 145
已结题

关于#python#的问题:如果两侧河岸上的狮子数量大于羚羊数量

写一个程序来解决这样一个问题:3 只羚羊和3 只狮子准备乘船过河,河边有一艘能容纳2 只动物的小船。但是,如果两侧河岸上的狮子数量大于羚羊数量,羚羊就会被吃掉。
找到运送办法,使得所有动物都能安全渡河。
每个循环每个分支每个变量可以有注释

  • 写回答

6条回答 默认 最新

  • 白驹_过隙 算法领域新星创作者 2022-12-26 15:07
    关注

    代码的输出结果含义是小船每次一来一回载的动物

    img

    from collections import Counter
    from random import sample, randint
    class Solution:
        """解决问题的方案类"""
    
        def __init__(self):
            """初始化属性"""
            self.left = ['羚羊'] * 3 + ['狮子'] * 3  # 后面用到了Counter,所以这里可以用字符串表示,不用0,1表示,更直观一点
            self.left_checkpoint = []  # 左边的存档,用于试错后恢复
            self.right = []
            self.right_checkpoint = []
            self.result = [[]]  # 结果,给个初始值是为了避免out of index的情况,取结果的时候切片即可
            self.result_checkpoint = []
            self.r_direction = True  # True为右,False为左
    
        def go(self):
            """渡河"""
            if self.r_direction:  # 向右渡河
                boat = sample(self.left, 2)
                for i in boat:
                    self.left.remove(i)
                    self.right.append(i)
            else:  # 向左渡河
                if len(self.right) > 1:  # 这里判断是为了避免sample取的时候越界(从1个里面取2个)
                    boat = sample(self.right, randint(1, 2))
                else:
                    boat = sample(self.right, 1)
                for i in boat:
                    self.right.remove(i)
                    self.left.append(i)
            return boat
    
        def judge(self):
            """判断"""
            if self.left and self.right:
                left_counter = Counter(self.left)
                right_counter = Counter(self.right)
                if (left_counter['羚羊'] and left_counter['羚羊'] < left_counter['狮子']) or \
                        (right_counter['羚羊'] and right_counter['羚羊'] < right_counter['狮子']):
                    return False
            return True
    
        def checkpoint(self):
            """检查点"""
            self.left_checkpoint, self.right_checkpoint, self.result_checkpoint = \
                self.left.copy(), self.right.copy(), self.result.copy()
    
        def reset(self):
            """读档"""
            self.left, self.right, self.result = \
                self.left_checkpoint.copy(), self.right_checkpoint.copy(), self.result_checkpoint.copy()
    
        def get_result(self):
            """模拟渡河过程,获取结果"""
            while len(self.right) < 6:
                self.checkpoint()  # 存档
                boat = self.go()  # 渡河
                boat.sort()
                if self.judge() and boat != self.result[-1]:  # 这里判断是为了避免相同的人来回的情况,以求尽可能少的解
                    self.r_direction = not self.r_direction  # 调转船头
                    self.result.append(boat)
                else:
                    self.reset()  # 读档
            return self.result[1:]
    
    
    def main():
        """主函数"""
    
        repeat = 10000  # 重复执行次数
        result_set = set()  # 解的集合
        solution = Solution()
    
        for _ in range(repeat):
            result = solution.get_result()
            result_set.add(str(result))
            solution.__init__()
    
        print(f'经{repeat}次执行,共得到{len(result_set)}种不同的结果,结果如下:', end='\n\n')
        for result in result_set:
    
            print(result)
    if __name__ == '__main__':
        main()
    
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(5条)

报告相同问题?

问题事件

  • 系统已结题 1月3日
  • 已采纳回答 12月26日
  • 修改了问题 12月26日
  • 创建了问题 12月26日

悬赏问题

  • ¥15 想用adb命令做一个通话软件,播放录音
  • ¥30 Pytorch深度学习服务器跑不通问题解决?
  • ¥15 部分客户订单定位有误的问题
  • ¥15 如何在maya程序中利用python编写领子和褶裥的模型的方法
  • ¥15 Linux权限管理相关操作(求解答)
  • ¥15 Bug traq 数据包 大概什么价
  • ¥15 在anaconda上pytorch和paddle paddle下载报错
  • ¥25 自动填写QQ腾讯文档收集表
  • ¥15 DbVisualizer Pro 12.0.7 sql commander光标错位 显示位置与实际不符
  • ¥15 android 打包报错