经典算法问题——第一问

问题:有25匹马,速度都不同,但每匹马的速度都是定值。现在只有5条赛道,无法计时,即每赛一场最多只能知道5匹马的相对快慢。

问最少赛几场可以找出25匹马中速度最快的前3名?

最近想通过经典算法问题加强算法的学习和算法在实践中的应用,便搜罗了一堆问题。首先上面列出的这个问题很有意思,本文记录一下代码,与大家交流和学习。

代码如下:

  #!/usr/bin/env python
  # -*- coding: utf-8 -*-
 1 from random import *
 2 
 3 print('本程序只支持马匹数与公路数能整除的值,有余数的暂不支持!!!
', '='*50)
 4 roads = int(input('请输入公路数:'))
 5 horses = int(input('请输入马匹数:'))
 6 order = int(input('你要取前几名?'))
 7 races = []      # 比赛分组数
 8 groups = []     # 各分组成员编号
 9 results = []    # 分组赛结果
10 result = []     # 第一排名
11 rank = []       # 后续排名
12 
13 # 随机分配成员速度
14 def create_speed(horses):
15     speeds = []
16     for i in range(horses):
17         # 强迫症,去除值小于10且相等的值
18         speed = 0
19         while speed < 10 or speed in speeds:
20             speed = int(random()*100)
21         yield speed
22 
23 # 小组赛分组
24 n = divmod(horses, roads)   # 这里本求解带余数的情况,但是问题较复杂,暂不支持
25 for i in range(n[0]):
26     races.append(chr(65+i))
27 
28 times = len(races)
29 
30 # 小组成员排号,并赋予速度
31 n = 0
32 for each_alpha in races:
33     group = {}
34     for digit in range(1, roads+1):
35         member = each_alpha+str(digit)
36         group[member] = next(create_speed(horses))  # 用生成器生成速度
37         n += 1
38         if n >= horses:
39             break
40     groups.append(group)
41 
42 # 比赛排名
43 for i in range(len(groups)):
44     ma = sorted(groups[i].items(), key=lambda r: r[1], reverse=True)
45     #ma = max(groups[i], key=groups[i].get)
46     results.append(ma)
47 
48 for j in range(len(results)):
49     result.append(results[j][0])
50 # 各组第一名排名
51 result = sorted(result, key=lambda r:r[1], reverse=True)
52 
53 # 打印结果
54 print('='*30)
55 print('比赛次数:第 %d 次' %(times))
56 print('小组赛各组排名:',results)
57 
58 times += 1
59 print('='*30)
60 print('比赛次数:第 %d 次' %(times))
61 print('小组赛第一名排名:',result)
62 print('第一名:%s  速度:%s km/h' %(result[0][0], result[0][1]))
63 
64 # 加赛,排出其它名次
65 for x in results:
66     y = 0
67     while y <= order-1:
68         if result[y] in x:
69             for z in range(order-y):
70                 rank.append(x[z])
71             break
72         else:
73             y += 1
74 times += 1
75 rank = sorted(rank, key=lambda r: r[1], reverse=True)
76 rank.pop(0)
77 
78 print('='*30)
79 print('比赛次数:第 %d 次' %(times))
80 print('第二名:%s  速度:%s km/h' %(rank[0][0], rank[0][1]))
81 print('第三名:%s  速度:%s km/h' %(rank[1][0], rank[1][1]))

结果如下:

本程序只支持马匹数与公路数能整除的值,有余数的暂不支持!!!
 ==================================================
请输入公路数:5
请输入马匹数:25
你要取前几名?3
==============================
比赛次数:第 5 次
小组赛各组排名: [[('A5', 79), ('A3', 75), ('A1', 68), ('A4', 53), ('A2', 19)], [('B1', 81), ('B5', 45), ('B2', 32), ('B3', 16), ('B4', 16)], [('C4', 71), ('C3', 57), ('C1', 51), ('C5', 13), ('C2', 10)],
[('D5', 98), ('D2', 77), ('D4', 36), ('D3', 29), ('D1', 14)], [('E1', 88), ('E5', 65), ('E2', 61), ('E3', 30), ('E4', 30)]] ============================== 比赛次数:第 6 次 小组赛第一名排名: [('D5', 98), ('E1', 88), ('B1', 81), ('A5', 79), ('C4', 71)] 第一名:D5 速度:98 km/h ============================== 比赛次数:第 7 次 第二名:E1 速度:88 km/h 第三名:B1 速度:81 km/h

此代码并未涉及太多算法思想,倒是应用了几个python的小工具(暂且叫它小工具吧),例如 生成器、匿名函数和 sort 方法的结合、还有python数据对象的应用 等。

对于此题的解答并不完美,只体现了大体过程,要想深入理解解题过程,可参考其它人的思路。

原文地址:https://www.cnblogs.com/nimo97/p/9779474.html