zoukankan      html  css  js  c++  java
  • python 比赛 组合问题

    比赛 组合问题

    简述:已知有两支乒乓球队要进行比赛,每队各出三人;
    甲队为a,b,c三人,乙队为x,y,z三人;
    已抽签决定比赛名单。

    问题:有人向队员打听比赛的名单。a说他不和x比,c说他不和x,z比,请编程序找出三队赛手的名单。

    li1 = ['a','b','c']
    li2  = ['x','y','z']
    
    # 全排列 有九种
    allMatchs = [m+n for m in li1 for n in li2]
    
    print(allMatchs)
    
    ['ax', 'ay', 'az', 'bx', 'by', 'bz', 'cx', 'cy', 'cz']
    

    如果只是解决这个问题,肯定有简单点的办法,根据条件 a说他不和x比,c说他不和x,z比 去生成可能的结果
    现在 我想找找看 '田忌赛马' 两两捉对厮杀的 共有多少种组合

    先确定 结果的形式: [{'a':'x','b':'y','c':'z'},{...}...]

    #  结果集合 操作的行 列索引 
    def nextProp(res,rIndex,cIndex,li1,li2):
        v = li2[cIndex]
        keys = []
       ## 
        for e in li1:
            if not res[rIndex].get(e):
               keys.append(e)
        newRows = []
        for kIndex in range(len(keys)):
            if kIndex==0:
               res[rIndex][keys[kIndex]] =v
               continue
            else:
                newRow = res[rIndex].copy()
                newRow.pop(keys[kIndex-1]) ##  把前面 kIndex==0 时候赋的值也copy过来了 去掉
                newRow[keys[kIndex]] = v
                newRows.append(newRow) ## 循环内部先使用新的list 不要影响循环
        res+=newRows
                     
    
    def getAllOptions(li1,li2,res=None):
        if not res: # 为空,第一次 初始化res
            res = []
            for e in li1:
                row = {e:li2[0]}
                res.append(row)
        for cIndex in range(1,len(li2)):
            for rIndex in range(len(res)):
                nextProp(res,rIndex,cIndex,li1,li2) # 填下一个属性
        return res
                    
    
    opts = getAllOptions(li1,li2)
    for e in opts:
        print(e)
    
    {'a': 'x', 'b': 'y', 'c': 'z'}
    {'b': 'x', 'a': 'y', 'c': 'z'}
    {'c': 'x', 'a': 'y', 'b': 'z'}
    {'a': 'x', 'c': 'y', 'b': 'z'}
    {'b': 'x', 'c': 'y', 'a': 'z'}
    {'c': 'x', 'b': 'y', 'a': 'z'}
    

    a说他不和x比,c说他不和x,z比, 现在就可以据此排除了,将刷选条件写成 回调函数

    def filterOptions(opts,*fns):
        res = []
        for e in opts:
            flag = True
            for fn in fns:
                if not fn(e):
                    flag = False
                    break
            if flag:
                res.append(e) # 没有因为不符合条件break 到这里就可以加进结果集了
        return res
    
    def f1(e):
        return e.get('a') !='x'
    def f2(e):
        return e.get('c')!='x' and e.get('c')!='z'
    
    res = filterOptions(opts,f1,f2)
    print(res)
    
    [{'b': 'x', 'c': 'y', 'a': 'z'}]
    

    python中对list dict中的查询遍历操作等全靠循环,一时间想不起来了....
    到时新技能get:

    arr = [2,45,50,24,35]
    for i in arr:
        if i>50:
            break
    else:
            print('arr里没有比50大的数!')
    
    arr里没有比50大的数!
    

    for 和 else 类似于 if和else,当for里没有break的时候,就会进去else

    for i in arr:
       pass
    else:
            print('arr里没有比50大的数!')
    
    arr里没有比50大的数!
    

    for 里if不是关键, 关键看break, 有break没else,没break有else

    可以在 for里用if exp :break 筛除, 剩下的进入else中处理

    import math #
    l = [2, 3]
    for i in range(5, 101): #第一层循环,从5到100
        for j in range(2, int(math.sqrt(i))+1): #一个数的最大因数是它的平方根
            if i%j == 0: #如果出现整除说明有因子
                break 
        else:
            l.append(i) #for正常执行(包括contine)完会执行else,break不会执行else
    print(" ".join(map(str, l))) #先将列表中的元素变为字符串再用空格连接输出
    
    2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71 73 79 83 89 97
    
    
    
  • 相关阅读:
    1052 Linked List Sorting (25 分)
    1051 Pop Sequence (25 分)
    1050 String Subtraction (20 分)
    1049 Counting Ones (30 分)
    1048 Find Coins (25 分)
    1047 Student List for Course (25 分)
    1046 Shortest Distance (20 分)
    1045 Favorite Color Stripe (30 分)
    1044 Shopping in Mars (25 分)
    1055 The World's Richest (25 分)
  • 原文地址:https://www.cnblogs.com/ShawSpring/p/10818889.html
Copyright © 2011-2022 走看看