经典算法问题——第一问
问题:有25匹马,速度都不同,但每匹马的速度都是定值。现在只有5条赛道,无法计时,即每赛一场最多只能知道5匹马的相对快慢。
问最少赛几场可以找出25匹马中速度最快的前3名?
最近想通过经典算法问题加强算法的学习和算法在实践中的应用,便搜罗了一堆问题。首先上面列出的这个问题很有意思,本文记录一下代码,与大家交流和学习。
代码如下:
#!/usr/bin/env python
# -*- coding: utf-8 -*-
1 from random import * 2 3 print('本程序只支持马匹数与公路数能整除的值,有余数的暂不支持!!!\n', '='*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数据对象的应用 等。
对于此题的解答并不完美,只体现了大体过程,要想深入理解解题过程,可参考其它人的思路。