【问题标题】:Winner of a tournament in O(N) and rank of the players in O(NLogN)O(N) 锦标赛的获胜者和 O(NLogN) 中的玩家排名
【发布时间】:2015-07-23 14:00:08
【问题描述】:

在 N 名球员参加的网球锦标赛中,每个球员都与其他球员一起比赛。 以下条件始终成立- 如果玩家 P1 赢得了与 P2 的比赛并且玩家 P2 赢得了 P3,那么玩家 P1 也击败了 P3。 在 O(N) 时间和 O(1) 空间中找到锦标赛的获胜者。在 O(NlogN) 时间内查找玩家排名。 我的解决方案: 输入是一个布尔矩阵,其中元素 matrix[i][j] 表示玩家 i 是否赢得玩家 j。

bool win[][]= {
    {0, 0, 1, 1, 1, 0, 1},
    {1, 0, 1, 1, 1, 1, 1},
    {0, 0, 0, 1, 1, 0, 0},
    {0, 0, 0, 0, 1, 0, 0},
    {0, 0, 0, 0, 0, 0, 0},
    {1, 0, 1, 1, 1, 0, 1},
    {0, 0, 1, 1, 1, 0, 0}
};

所以可以像这样找到获胜者,

int winner = 0;
for (int i = 1; i < PLAYER_COUNT; ++i) {
    if (win[i][winner])
        winner = i;
}
return winner;

为了获得玩家的排名,我想拓扑排序会是一个不错的选择。如果玩家 1 赢得玩家 2,则添加一条边,例如这个 P1-> P2。如果玩家 1 在这里获胜,那么它对所有其他玩家都有优势。然后以获胜者为源顶点的拓扑排序,将给出玩家的排名。 我的解决方案正确吗?还有其他有效的解决方案吗?任何帮助都会很棒,在此先感谢。

【问题讨论】:

  • 显示您的代码。如果有 特定 错误,请随时询问。这不是“做我的功课”、代码审查或教程网站。
  • 你提到的永远成立的条件太强了。这个条件将使玩家赢得所有人。这应该是您的搜索功能的标准。根据我的眼球,在这种情况下,它是 2 号玩家。
  • 另外:C 和 C++ 是不同的语言。
  • 我认为这是一个理想的世界,每个玩家都有一个可量化的技能水平,更好的玩家总是获胜,从而消除了真实数据的大部分复杂性。
  • @Jefffrey 您不必遍历整个矩阵。你从随机玩家开始,然后找到赢得那个人的人,然后迭代,直到你找不到任何人赢得他。我认为它确实闻起来 O(n)。

标签: c++ c algorithm data-structures


【解决方案1】:

条件

如果玩家 P1 赢得了与 P2 的比赛并且玩家 P2 赢得了 P3

定义了一个总排序,即如果我们为“P2打败P1”定义P1 &lt; P2,我们有一个传递排序关系&lt;,它可以完全用作常规的less-than关系排序或查找最大值。因此,对于实现,我们可以定义谓词bool lessThan(int p1, int p2),它将简单地在O(1) 的矩阵中查找p1p2 关系。然后使用谓词进行“最大”搜索,即线性(O(N)),或用于排序(排名),即O(N log N)

【讨论】:

  • 我们如何部署小于谓词来排序 n log n?
  • @abksrv 选择在O(n log n) 中运行的任何体面的排序算法(合并排序、堆排序)并在其中使用此谓词而不是&lt; 进行比较。
  • Quickselect 和 Quicksort 在实践中会是不错的选择,但需要修改以保证最坏情况下的 O(n) 和 O(n log n)。
【解决方案2】:

您寻找获胜者的方法似乎是正确的。事实上,假设真正的获胜者号码是W。当你在你的循环中你有i==W,你将永远有win[i][winner]==1,因为玩家W赢得了其他人。因此,您将设置winner=W,并且永远不会再更改它,因为没有人赢过W

你的代码也是O(N),所以我认为它解决了第一个问题。

对于第二个问题,是的,拓扑排序可以,但一个简单的实现将是O(N^2)。但是,请注意您的win 表实际上提供了strict total order。因此,您可以应用任何标准排序算法,并比较两个玩家,只需检查一个是否赢了另一个。也就是说,只需使用

bool less(int playerA, int playerB) {
    return win[playerA][playerB];
}

std::sort.

这种严格全序的概念还为您找到获胜的算法提供了另一种证明。

这是您的示例的完整代码:http://ideone.com/99DIQk

【讨论】:

  • 但是在这种情况下,我们必须将每个玩家与其他玩家进行比较,对吗?那么,这使得 O(N2) 对吗?
  • @vignesh,许多排序算法只使用O(N log N)比较。
  • 不,我问的是这个函数 bool less(int playerA, int playerB)
  • @vignesh,这个函数只是比较两个给定的玩家,并在O(1) 中执行此操作。所以每次对less的调用是O(1),而这样的调用总数是O(N log N)
  • 你能用一个简单的 4 名玩家来解释一下吗?
猜你喜欢
  • 2020-05-08
  • 1970-01-01
  • 2021-10-22
  • 1970-01-01
  • 1970-01-01
  • 2016-10-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多