震惊!人生苦短,我用python来玩田忌赛马

一读标题笑死自己哈哈哈,最近猪哥(玩得敲好的彭友)找我帮忙解决他不会作业哈哈哈,他们公司自己出的笔试题哈哈哈,希望别被他们出题人看见哈哈哈,回想猪哥说的一句话,万一这就是以后你遇到的试题呢哈哈哈。突然发现自己已经小半年没玩Python了,一上手手都生了,还真是那句话,三天不摸手生了都。
在这里插入图片描述

使用 python 函数实现田忌赛马

要求一

现在我们
将田忌的马抽象为一个列表 [2,5,8],
齐王的马抽象为另一个列表 [3,6,9],
分别代表各自的下、中、上等马(我自己读到这里就记住值越大,马越好,这样理解就不会错了)。
设计一个函数 race(),将两个列表作为参数传递给race(),将策略抽象为代码使田忌赢得比赛,函数返回每轮对阵情况:
上代码

# coding=utf-8
from typing import *


def race(tian: List[int], qi: List[int]) -> List[List[int]]:
    # 给两个列表的数排序
    tian.sort()
    qi.sort()

    # 把最弱的放到最后
    # 这里运用了索引的知识,第一个索引是除了第一个元素不取(也就是索引为0的)其他的都取;
    # 第二个是取到第一个元素,然后作为一个列表里面的一个元素
    tian = tian[1:] + [tian[0]]

    # 返回每轮对阵情况
    return list(zip(tian, qi))


if __name__ == '__main__':
    tianji = [2, 5, 8]
    qiwang = [3, 6, 9]
    result = race(tianji, qiwang)
    print(result)

要求二

现在将马分为 劣 、下、中、上、优五等,五局三胜制,抽象为列表[2,4,6,8,10] 与 [1,3,5,7,9] ,其他条件不变(齐王仍然准守规则,田忌继续不按照套路出牌),计算出田忌有多少种赢得比赛的可能
上代码

# coding=utf-8
import itertools


def race(qiwang, tianji):
    # 用迭代获取田忌所有派遣马匹的方式(['13579',5])
    tianji_l = list(itertools.permutations(tianji, len(tianji)))
    # 全部赛果
    result = []
    # 遍历所有的赛马方式
    for i in tianji_l:
        # 一轮的比赛结果
        result_1 = []
        # 一轮比拼中,双方马匹对阵情况,i为tianji(i是从tianji_l获取的)
        for horses in zip(i, qiwang):
            # 如果田忌的马值比齐王的小
            if horses[0] < horses[1]:
                # 那这一轮就是田忌输
                result_1.append('lose')
            else:
                # 反之,这一轮就是田忌赢
                result_1.append('win')
        # 如果这一轮赢三次及以上
        if result_1.count('win') >= 3:
            # 田忌就赢了,将赢了的追加到result里面
            result.append('win')
    return len(result)


if __name__ == '__main__':
    tian = [1, 3, 5, 7, 9]
    qi = [2, 4, 6, 8, 10]
    all_result = race(qi, tian)
    print(all_result)

要求三

如果你是齐王,已知同级别中己方的马优于田忌的马,事先不知道对方派遣顺序,不过可以根据上一轮对方的派出的马匹制定本轮的选择。制定一种派遣策略,使赢得比赛的几率最大。

第三题我是真不知道咋做了(想这个脑子都长草了!这是亲爷熬夜给我想出来的,可能不是最优,需要点聪明脑子,如果有更好的想法可以私信我,欢迎讨论)

解题思路
田忌以劣胜优的策略在于输的时候输的比较多,但是赢的时候只是微弱优势赢
如 10-1 8-9 6-7 4-5 2-3 (齐王1:田鸡4)
那想让齐王尽可能获胜的办法就是拉开这个「微弱优势」

方法
齐王第一次排出2的
往后每次分两种情况,
1.田忌赢了,那我们就可以拿出上轮田忌的x-1的参加下一轮。
2.田忌输了,可以继续拿当前最小的出来。
如果x-1的没了,就出最差的那匹,如此循环

这种方法仍然会失败 如田忌按照3 5 7 9 1这样出

上代码

# coding=utf-8

from itertools import permutations
from typing import *

tian = [1, 3, 5, 7, 9]
qi = [2, 4, 6, 8, 10]


def play() -> float:
    global qi
    win_count = 0
    cnt = 0
    for a, b, c, d, e in permutations(tian, 5):
        qi = [2, 4, 6, 8, 10]  # 复原
        cnt += 1
        tian_rank = [a, b, c, d, e]
        qi_rank = [qi.pop(0)]  # 初始化
        for index, last_tian in enumerate(tian_rank[:4]):
            qi_rank.append(strategy(last_tian, qi_rank[index] > tian_rank[index]))  # 每次根据上一次tian的和输赢制定策略
        # 根据两个rank算输赢
        win_count += winner(qi_rank, tian_rank)
    # 返回概率
    return float(win_count) / float(cnt)


def strategy(last_tian: int, is_win: bool) -> int:
    global qi
    # 如果齐王上轮赢了,继续拿最小的出来
    if is_win:
        return qi.pop(0)
    # 如果齐王上轮输了
    else:
        # 如果x-1的存在,就拿出来
        if last_tian - 1 in qi:
            return qi.pop(qi.index(last_tian - 1))
        # 否则还是拿最小的
        else:
            return qi.pop(0)


def winner(qi: List[int], tian: List[int]) -> bool:
    cnt = 0
    for q, t in zip(qi, tian):
        cnt += q > t
    return cnt >= 3


if __name__ == '__main__':
    print(play())

这样算出来的概率是0.075,
在这里插入图片描述

感觉前面两个算法题加油扣脑壳是可以凑合写出来的,第三个是真难度(当然对于大佬来说小事一桩)

https://blog.csdn.net/hanhanwanghaha欢迎关注这个超级无敌可爱的人鸭,有什么问题留言私信皆可,看见必回!
创作不易,如有转载,请注明出处

猜你喜欢

转载自blog.csdn.net/hanhanwanghaha/article/details/110846070