【问题标题】:Race Car Puzzle赛车拼图
【发布时间】:2011-03-17 03:02:33
【问题描述】:

你能帮我解决这个我找不到好的答案的谜题吗!

有 49 辆赛车以独特的速度比赛。还有一条赛道,最多可以让 7 辆车一起比赛。我们需要找到组中第 25 快的汽车。我们没有秒表来测量时间(所以我们只能测量每辆车相对于比赛中其他 6 辆车的相对速度)。最少需要多少场比赛?

【问题讨论】:

  • 您是要求我们这样做,还是您是需要帮助的人?
  • 您的标签具有误导性 - 算法、数据结构,在您的问题中,您是在寻求难题的答案。你想要什么?
  • @pavanred,使用算法和 DS,我想要一个谜题的答案(以下是 3 个标签)
  • 您是在问“最少需要多少场比赛?”在最好的情况下,还是在最坏的(一般)情况下?
  • @belisarius:下限严格大于 7 场比赛。您需要对所有汽车进行比赛才能知道它们的相对速度是多少,并且您至少可以做到 7,但是您有 7 个不相交的集合,没有相关信息。无论如何, sorted 在这种情况下没有相关意义。您有 49 辆汽车,它们没有分配编号,您分配给它们的任何顺序都是您自己的。

标签: algorithm puzzle


【解决方案1】:

遵循辩证法的灵感。分成 7 个随机组并与每个组比赛,然后与这些组的中位数比赛。这辆车成为支点,我们已经直接或间接地知道它与其他 30 辆汽车的关系(这是中位数的属性)。所以把它放在一起。其他 18 场比赛我们需要进行 3 场比赛,包括支点。旋转后,我们最多需要递归 33 辆汽车。继续。我最终参加了 29 场比赛。即使您假设需要完整排序,但实际上并非如此,17 场比赛也有一个下限(真正的下限会更低),远小于 29 场。所以我怀疑这不是正确的答案,但由于这一直缺乏任何解决方案,这是一个次优的解决方案。如果你看一下关于排序网络的研究(这个问题是一次仅限于两辆车的比赛),找到最优网络是很困难的,最优网络仅适用于非常小的尺寸,绝对不超过 49。我不知道任何关于具有 7 路比较器的网络的研究。

也许有一个例子可以提供帮助。假设将汽车从最慢到最快编号,然后将它们排列在一个 7x7 矩阵中(任意排列,因为在比赛之前我们不知道速度)。

     [,1] [,2] [,3] [,4] [,5] [,6] [,7]
[1,]   34   25   45   43   26   21   13
[2,]   11   24    2   40   14   30   32
[3,]   27   19   29   42    4   17   46
[4,]   15   10   39   33    1    9    5
[5,]   28   18   41    8   23   20    6
[6,]   16    3   38    7   12   22   36
[7,]   31   44   48   35   49   37   47

然后让我们对每一列进行比赛,并根据比赛结果对它们进行排序:

     [,1] [,2] [,3] [,4] [,5] [,6] [,7]
[1,]   11    3    2    7    1    9    5
[2,]   15   10   29    8    4   17    6
[3,]   16   18   38   33   12   20   13
[4,]   27   19   39   35   14   21   32
[5,]   28   24   41   40   23   22   36
[6,]   31   25   45   42   26   30   46
[7,]   34   44   48   43   49   37   47

现在让我们对第 4 行(中位数)进行比赛,并根据结果重新排列列

     [,1] [,2] [,3] [,4] [,5] [,6] [,7]
[1,]    1    3    9   11    5    7    2
[2,]    4   10   17   15    6    8   29
[3,]   12   18   20   16   13   33   38
[4,]   14   19   21   27   32   35   39
[5,]   23   24   22   28   36   40   41
[6,]   26   25   30   31   46   42   45
[7,]   49   44   37   34   47   43   48

现在观察中位数的中位数(元素 [4,4])比上方和左侧的任何汽车都快,但比下方和右侧的任何汽车都慢(这是中位数的属性)。对于其他赛车(左下和右上)我们​​不知道,所以我们需要与 [4,4] 比赛,一次 6 场比赛(3 场比赛)。现在我们观察到 26 辆汽车比 [4,4] 慢,因此中位数必须是其中之一。无需再与其他任何人比赛。现在对这 26 辆汽车重复这个过程。

【讨论】:

  • 这个解决方案的问题是,即使经过 8 次比较,您仍然不知道中位数在集合中的位置的中位数...因为唯一可以安全丢弃的象限是右下角
【解决方案2】:

我有一个只需要 17 场比赛的解决方案。

不过,首先让我解释一个需要 32 场比赛的简单解决方案。将汽车分成 7 组,每组 7 辆,每组比赛(7 场比赛)。重复 25 次:从每组中选出剩下的最快的汽车参加比赛,并将获胜者放在一边(25 场比赛)。 25 场比赛中的第一场决定了最快的赛车(#1),第二场比赛决定了#2,依此类推。

现在只有 17 场比赛的解决方案:

我们的策略是首先确定 24 辆最快的汽车(我们称这些汽车为“快速”)。然后我们会找到最快的(#25)。

将赛车随机放置在 7x7 网格上,并在每排比赛(7 场比赛)。 然后,对每场比赛(第 8 场比赛)的第 3 名完赛者进行比赛,并按第 3 名完赛者的速度对行进行排序。

所以,经过 8 场比赛,我们得到了这样的结果:

每个网格单元代表一辆汽车。箭头指向更快的汽车。请注意,箭头是可传递的。

我们已经可以识别出 8 辆“快速”的汽车:

我们怎么知道它们速度很快?看看蓝色的“x”。只有 23 辆汽车可能比它快(那些不在右下角的 5x5 中)。所以,它肯定是“快速的”。您可以为其他 x 验证这一点。

我们已经确定了 24 辆“快速”汽车中的 8 辆。让我们从未来的考虑中删除这 8 个。我们现在正在寻找剩余汽车中最快的 16 辆。我们的七个组的尺寸分别为 4、4、5、7、7、7 和 7。(对于图表,每当我们移走一辆车时,让我们将剩余的车滑到左侧。)

让我们以每组剩余第二快的赛车进行比赛,并相应地对行进行排序(第 9 场比赛)。和以前一样,我们可以识别出 4 辆汽车,它们肯定是 16 辆最快的(即“快速”):

我在可能被移除的汽车所在的单元格中着色,但这还没有效果。
我们已经确定了 12 辆“快速”汽车。去掉“快速”的汽车,我们在剩下的汽车中寻找最快的 12 辆。我们的团体人数在 2 到 7 人之间。 让我们以每组剩余第二快的赛车进行比赛,并相应地对行进行排序(第 10 场比赛)。我们确定了 12 辆最快(即“快速”)中的 2 辆汽车:

(剩下 10 辆“快速”的汽车。)

我们可以再重复上一步两次(第 11 和第 12 场比赛)。每次我们多移走 2 辆车。但是,请注意,一行/组中可能有 0 或 1 辆汽车。如果其中有 1 辆车,我们将与那辆车比赛,而不是“剩余第二快”。如果那辆车赢了,我们就知道它是“快速”的,也是第二快的第二名车。在任何情况下,我们都会识别出 2 辆“快速”汽车。 (剩下 6 辆“快速”的汽车。)

在 12 场比赛之后,我们已经确定并移除了 18 辆“快速”赛车。我们需要识别剩下的 6 辆“快速”汽车。

现在让我们简单地比赛每组中剩余最快的赛车(第 13 场比赛),并相应地对行进行排序。获胜者是“快速”。还剩 5 个。

在最后一场比赛之后,只有 2 辆赛车可能是剩余最快的赛车。蓝色的o:

此外,剩余第二快的汽车是蓝色“o”或绿色“o”。让我们来比赛这 5 辆车(第 14 场比赛),前两名完赛者肯定是“速度很快”。还剩 3 个。

让我们重复最后两个步骤/比赛来确定最后 3 辆快速赛车(第 15 和第 16 场比赛)。

因此,我们确定了 24 辆“快速”汽车。剩下的最快的车必须是第 25 快的。我们只需在每排/组(第 17 场比赛)中以最快的车比赛即可找到这辆车。

【讨论】:

  • 我非常喜欢!尽管我不能确定它在每种情况下都有效。几个问题:当前排没有足够的赛车时,你会在最后 7 场比赛中做什么?例如,如果一排是空的,或者在第 14 和第 16 场比赛中的汽车数量少于适当数量?此外,你是如何得到这个解决方案的?从某种意义上说,这似乎是最佳选择,因为您不会将两辆车一起比赛两次,而且您不会获得比您需要的更多信息。但是有证据证明 17 是一个下限吗?
  • 如果一行为空,只需将其从网格中删除。在第 14 和第 16 场比赛中,如果缺少一些 o,则将它们从比赛中省略。最快的 2 仍将在现有的 o 中。在找到 32 场比赛的“简单解决方案”后,很明显我可以做得更好!如果 17 是最佳值,我会感到震惊。我的三场比赛只能识别一辆车。
  • 这看起来很有希望......我不是数学家,但这个问题一直困扰着我。现在我将不得不尝试编写脚本以查看它是否有效,以及何时有效:)
  • @Tom 我尝试了你的解决方案几次,它的工作和摇滚 :) 赏金是你的。谢谢!
  • @Tom,看起来你不会成为一个 F# 人,但如果你关心 take a look,我已经尝试实现它来测试它。从第 14 场比赛开始看起来不太好,我想是因为我没有正确理解你。 (如果向下滚动,有一个示例输出)
【解决方案3】:

【讨论】:

  • 我无法找到该算法在我的问题中的应用;因为我的输入集不是同时所有 49 辆车(而是我一次只能比赛 7 辆车并且知道它们的相对位置);如果您能详细说明这将有所帮助。
  • 查找“Median of Medians 算法”并将文本中的数字 5 替换为您的案例中的数字 7。
  • 中位数的中位数不适用于第 25 快的汽车在其 7 辆汽车中不是第 4 快的情况。
  • @Dialectus,好主意,但它应该是一个答案。
  • @piccolbo,这只是一个想法,而不是完整的答案。我真的不知道如何实施该解决方案。
【解决方案4】:

http://www.sureinterview.com/shwqst/1062001

第一轮

  1. (7 场比赛)将赛车分成 7 组,并获得每组内的顺序。
  2. (1 场比赛)取 7 个中位数并得到顺序。找到中位数的中位数(表示为 o)。在下面的例子中,它是 34。
  3. (3 个种族) 求中位数的排名。从左下角(25~33)和右上角(13~21)取6个元素,与o(34)比赛。 3轮之后,我们知道这个中位数在整个集合中的排名。最好的情况是 o 是全球中位数(第 25 快)。最坏的情况是 o 是第 16 或第 34 快的。

此示例显示了一种可能的最坏情况。

1   2   3   4   13  14  15  <- group 1
5   6   7   8   16  17  18 
9   10  11  12  19  20  21     ...
22  23  24  34  35  36  37
25  26  27  38  39  40  41  <- group 5
28  29  30  42  43  44  45  <- group 6
31  32  33  46  47  48  49  <- group 7

第二轮

我们想以二分搜索方式找到其他中位数的排名。

  1. (3 场比赛)选择小于 34 的中位数,即 12。与左下角和右上角的汽车比赛。经过3场比赛,我们知道它的排名是12。

现在,这两个中位数之间的差距最多为 21,如本例所示。

第三轮

重新排列 21 辆汽车(>12 和

13  14  15  <- group 1
16  17  18 
19  20  21     ...
22  23  24
25  26  27  <- group 5
28  29  30  <- group 6
31  32  33  <- group 7

每一行仍然是排序的。

  1. (1 场比赛)再次求中位数的中位数,即 23。
  2. (1 种族)找到它的排名。经过这一步,我们知道上一步的车肯定排在第 23 位。
  3. (1 个种族)类似于二分搜索,检查另一个中位数 29 的排名。
  4. (1 场比赛)对 23 ~ 29(不包括)之间的所有赛车进行排序。找到第 25 快的汽车。

因此,最多需要 18 场比赛才能获得第 25 名最快的赛车。

【讨论】:

  • 好方法!但是,假设在确定“o”为第 34 位之后,您会发现“高于”它的中位数为第 28 位(而不是第 12 位)。你还能在 18 场比赛中找到第 25 名吗?如果没有更多的逻辑,我认为你实际上需要 21 场比赛。在第 2 轮中,您提到“我们想以二进制搜索方式查找其他中位数的排名”,但您找到的是 12 而不是 8。此外,该算法非常好,但可能不是最优的。这是一个非常有趣的问题!
  • 嗯,这个方法最坏的情况其实是像1 2 3 21 22 23 24 &lt;- group 14 5 6 26 27 28 29 7 8 9 30 31 32 33 ...10 11 12 34 35 36 3713 14 15 38 39 40 41 &lt;- group 516 17 18 42 43 44 45 &lt;- group 619 20 25 46 47 48 49 &lt;- group 7注意第一轮后(34找到),左下角和右上角也按列排序。此信息有助于减少种族数量。
【解决方案5】:

你不能通过确定汽车的确切位置来迭代地划分池吗?

随机选择一辆车作为枢轴 跑过其他 48 辆汽车,以 6 人一组的方式与枢轴车比赛 您现在知道枢轴车的确切位置了。

现在对集合中您知道包含位置 25 的部分运行相同的过程。如果剩余分区中的元素少于七个,则很容易确定。

这种最坏情况下的性能确实非常可怕,但可以通过以某种半智能方式选择连续的枢轴来缓解。

【讨论】:

    【解决方案6】:

    你总是可以在 8 场比赛中解决它... 让我们拿一辆 Pivot Car 说 Car1 并在 8 场比赛中与所有其他汽车比赛,并在 Car1 上取其他汽车的相对速度。 假设结果如下: Read Car#(Relative speed to Car1)


    第 1 场比赛:Car1-(0)、Car2-(+10)、Car3(+5)、Car4(+7)、Car5(-3)、Car6(-4)、Car7(+1)

    第 2 场比赛:Car1-(0)、Car8-(+10)、Car9(+5)、Car10(+7)、Car11(-3)、Car12(-4)、Car13(+1)

    第 3 场比赛:Car1-(0)、Car14-(+11)、Car15(+4)、Car16(+6)、Car17(-4)、Car18(-10)、Car19(+2)

    第 4 场比赛:Car1-(0)、Car20(+9)、Car21(+3)、Car22(+5)、Car23(-5)、Car24(-11)、Car25(+3)

    第 5 场比赛:Car1-(0)、Car26-(+8)、Car27(+2)、Car28(+6)、Car29(-6)、Car30(-12)、Car31(+4)

    第 6 场比赛:Car1-(0)、Car32-(+7)、Car33(+1)、Car34(+3)、Car35(-7)、Car36(-13)、Car37(+5)

    第 7 场比赛:Car1-(0)、Car38-(+6)、Car39(-1)、Car40(+2)、Car41(-8)、Car42(-14)、Car43(+6)

    第 8 场比赛:Car1-(0)、Car44-(+5)、Car45(-2)、Car46(+1)、Car47(-9)、Car48(-15)、Car49(+7)

    由于 Car1 是枢纽车,并且每辆车的速度在所有比赛中都是一致的,所以我们可以将所有结果组合在一起。

    如果您对相对速度(wrt car1)进行排序,您可以找出第 25 快的汽车。

    【讨论】:

    • “我们没有秒表来测量时间”
    • 不是时候...它的相对速度,您可以测量枢轴汽车 (Car1) 和其他汽车之间的相对速度。这就是为什么 Car1 的相对速度始终为 0,因为它是用自己测量的。
    • 比赛会告诉你每辆车比枢轴车快还是慢,但不会告诉你快多少。 (每场比赛后你不会得到任何数字——只有 7 辆车的排名)
    • 这里引用问题中的一句话:“我们没有秒表来测量时间(所以我们只能测量每辆车相对于比赛中其他 6 辆车的相对速度)。 " ==> 这意味着我们可以测量相对速度。
    猜你喜欢
    • 1970-01-01
    • 2010-09-21
    • 1970-01-01
    • 1970-01-01
    • 2013-06-04
    • 1970-01-01
    • 1970-01-01
    • 2013-10-20
    • 1970-01-01
    相关资源
    最近更新 更多