面试题:赛马问题
问题:一共有25匹马,有一个赛场,赛场有5个赛道,就是说最多同时可以有5匹马一起比赛。假设每匹马都跑的很稳定,不用任何其他工具,只通过马与马之间的比赛,试问,最少得比多少场才能知道跑得最快的5匹马?
解题思路:
比如:我们假设比赛完第六场后,我们得到下面的排序:(每组排序是——快马从左到右,各组头名的排序是——快马从上到下)
A组 A1 A2 A3 A4 A5
B组 B1 B2 B3 B4 B5
C组 C1 C2 C3 C4 C5
D组 D1 D2 D3 D4 D5
E组 E1 E2 E3 E4 E5
练习一下:
1.
有25匹马,一个5道的赛马场,最少比赛几次,能把这25匹马中的1,2,3名找出来,并排出1,2,3名?
2.
2009清华大学自主招生试题:64匹马赛跑,假设马发挥稳定且没有体力问题,如果一场比赛可以让8匹马同时赛跑,那么能否在50场比赛内排出所有名次。
1.把64匹马分成8组,先把每组排个序,共8场比赛。
2.把这8组8匹马两两合并为4组16匹马的有序组,每次合并需要3场比赛。
这里就是本题的关键所在:从其中任意选出两组,合并后的前4名肯定在两组的前4名这8匹马里,这8匹比一场就把两组的前4比出来了;对剩下的12马采取同样的策略,各取前4名,然后通过一场比赛决出整合后序列的5-8名,最后还剩8匹马,再为这8匹赛一次,这就是最后8名了。
3.把4组16匹马再两两合并为2组32匹马,每次合并需要7场比赛。
方法同上,实际上可以证明,两组有序的8k匹马合并成一组16k匹马,需要16k/4-1=4k-1场比赛。(之前每场比赛决出靠前的4名,最后一场比赛一次决出最后的8名)
4.把2组合并成1组,需要15场比赛。
这样的话,一共就是 8+4*3+2*7+1*15=49场比赛。
这就体现了信息学中“归并排序”的思想。归并排序具体工作原理如下(假设序列共有n个元素):
将序列每相邻两个数字进行归并操作(merge),形成floor(n / 2)个序列,排序后每个序列包含两个元素;
将上述序列再次归并,形成floor(n / 4)个序列,每个序列包含四个元素;
重复步骤2,直到所有元素排序完毕。
//////////////////////////////////////////
可以考虑类似归并排序的方法;
假设有A,B两组能"区分出任意两匹马的优劣"的马,每组8*k匹,且两组内的马按照优劣次序分别编号为:
A[1],A[2],,,A[8*k];
B[1],B[2],,,B[8*k];
现要合并两组成一组,且合并后的8*k匹马之间也能"区分出任意两匹马的优劣";
注意到:合并后的前4名总是在两组的前4名中;
1) 每次从两组各取前4匹,共8匹,进行比赛,决出前4名;
2) 继续从两组剩下的马中,每组各取前4匹(若有某组不足4匹,则从另一组中取多于4批使得总数为8匹),
决出剩下的马中的前4名;
3) 继续2),直到两组总共只剩下8批,一次比赛决出这8匹相互之间的名次;
可以看到,每次比赛总可以决出4个排位,且最后一次可以决出8个排位;
所以两组8*k批的马合并成一组16*k的马总共需要 (16*k-8)/4+1==4k-1场比赛;
具体到本题:
1) 分成8组,分别比赛,分出组内的名次; 需要赛 8 场
2) 将1)中的8组两两合并成4组,每组16(16*1)匹;每次合并需要 4*1-1==3场,
总共需要4次合并,总共需要赛 12 场;
3) 将2)中的4组两两合并成2组,每组32(16*2)匹;每次合并需要 4*2-1==7场,
总共需要2次合并,总共需要赛 14 场;
4) 将3)中的2组合并成1组64(16*4)匹;每次合并需要 4*4-1==15场,
所以总共需要 8 + 12 + 14 + 15 == 49 场;
///////////////////////////////////////////////////////
另一牛逼解答:
37场:先随意将马排成8*8阵型:
01 02 03 04 05 06 07 08
09 10 11 12 13 14 15 16
17 18 19 20 21 22 23 24
25 26 27 28 29 30 31 32
33 34 35 36 37 38 39 40
41 42 43 44 45 46 47 48
49 50 51 52 53 54 55 56
57 58 59 60 61 62 63 64
1、每一行赛一场,共八场。由对称性,不妨设每一行都是从左到右速度依次减慢。即01,09,17,25,33,41,49,57是八场的冠军。
2、下面说明,之后每4场总可以决出8个名次。
(1)各组冠军赛一场,(2)各组垫底赛一场,共两场,决出了第一名、第六十四名。且不妨设第一列各马速度由上至下依次变慢。即01是总冠军。
(3)现在,总第二名有两匹马候选,02,09。让02,09,10,17四匹马参与第三场。第三场另四匹呢?它们是有类似情况的最慢的几匹马。例如如果64是最慢的,第八列由快到慢依次是08,16,24,32,40,48,56,64,那么,让56,63,55,48四匹马参与第三场。由第三场的结果,总可以知道总第二、第六十三名。
下面说明,不管02,09,10,17赛得的结果如何,总第三、四名的候选马不会超过四匹。
若02获胜,那么总第三、四名的候选马只有03,04,09,以及10和17两匹中较快的一匹(这两匹已经赛过)
若09获胜,那么第三名实际上已经知道了,是02、10或17中较快的一匹。若是02,则第四名候选马是03,10,17。若是10,则第四名候选马是02,11,17。若是17,则第四名候选马是02,10,18,25。
于是,总第三、四名的候选马不会超过四匹。同理,总第六十二、六十一名的候选马也不会超过四匹。
(4)将上述总第三、四名的候选马、总第六十二、六十一名的候选马至多不超过八匹,赛一场,于是至此已经决出了前四名后四名共八个名次。
不断重复上述过程,直至7个4场后决出了56个名次。
3、最后还剩8个名次,用一场解决。
总计:8+4*7+1=37场。