我正在尝试在我的程序中实现一个括号(使用C#/。NET MVC)并且我试图找出一些算法。
例如,我有一个这样的括号,有8个条目(A,B,C,D,E,F,G,H)
我正在试图弄清楚是否有算法
取决于条目数,找到#of 每轮比赛
取决于条目数,用于a 特定游戏#,是什么 相应的游戏#在下一个 圆
例如,在这种情况下,对于8个条目,示例为:
我还想过将这些信息存储在一个表格中,但它似乎有点矫枉过正,因为它永远不会改变,但无论如何它仍然存在:
任何帮助将不胜感激!
干杯,
迪安
答案 0 :(得分:6)
问题第一部分的C#代码:
// N = Initial Team Count
// R = Zero-Based Round #
// Games = (N / (2 ^ R)) / 2
public double GamesPerRound(int totalTeams, int currentRound) {
var result = (totalTeams / Math.Pow(2, currentRound)) / 2;
// Happens if you exceed the maximum possible rounds given number of teams
if (result < 1.0F) throw new InvalidOperationException();
return result;
}
解决第(2)部分的下一步是知道给定回合的最小游戏数。一个直观的方法是通过for循环,但可能有一个更好的方法:
var totalTeams = 8;
var selectedRound = 2;
var firstGame = 1;
// If we start with round 1, this doesn't execute and firstGame remains at 1
for (var currentRound = 1; currentRound < selectedRound; currentRound++) {
var gamesPerRound = GamesPerRound(totalTeams, currentRound);
firstGame += gamesPerRound;
}
答案 1 :(得分:5)
引用@Yuck完美回答第一个问题。
问题第一部分的C#代码:
// N = Initial Team Count
// R = Zero-Based Round #
// Games = (N / (2 ^ R)) / 2
public double GamesPerRound(int totalTeams, int currentRound) {
var result = (totalTeams / Math.Pow(2, currentRound)) / 2;
// Happens if you exceed the maximum possible rounds given number of teams
if (result < 1.0F) throw new InvalidOperationException();
return result;
}
继续讨论第二个问题:
//G = current game.
//T = total teams
//Next round game = (T / 2) + RoundedUp(G / 2)
//i. e.: G = 2, T = 8
//Next round game = (8 / 2) + RoundedUp(2 / 2) = 5
public int NextGame(int totalTeams, int currentGame) {
return (totalTeams / 2) + (int)Math.Ceiling((double)currentGame / 2);
}
答案 2 :(得分:2)
我实际上是在最近自己解决了这个问题,并且偶然发现(也就是说,我已经解决了,但之前可能已经发现过)一个简洁的递归解决方案。
您从以种子订单排序的列表中的玩家列表开始。这在以后很重要。
整体算法包括将玩家列表分成两个,然后创建两个子锦标赛。这两个分赛事的获胜者将结束整个锦标赛的总决赛。
大多数锦标赛将头号种子选手放在第一轮的底部种子选手中。为了做到这一点,我使用了以下算法,但您可以将第一个n / 2
玩家放在一个列表中,其余的放在另一个列表中以创建一个锦标赛,种子1和2在第一轮播放(和种子3次播放4次,5次播放6次等。
我会在这里注意到,让顶级种子打底线种子的巧妙之处在于,如果你没有两名球员的力量,这个算法的顶级种子会在早期轮次。
当然,如果列表中只有两个玩家,你只需在他们之间创建一个匹配并返回。
所以你开始说一个64位玩家的名单。你将它分成两个32个玩家的列表,并递归创建两个子竞赛。您递归调用的方法应该返回表示子锦标赛的总决赛(整场锦标赛的半决赛)的匹配。然后你可以创建一个匹配作为整个锦标赛的总决赛,并将半决赛的nextMatch
设置为总决赛。
nextMatch
。希望这有帮助,如果您需要任何澄清,请告诉我们。)
答案 3 :(得分:1)
所以基本上是淘汰赛。
所以只需要List。
如果团队数量是偶数,算法将始终将第一和第二个团队放在一起。然后将计数器增加2并重复。
如果球队的数量是奇数,除了你随机选择一个“第一个周围”的胜利者并将其与奇数球队对抗之外,几乎可以做同样的事情。
在第一轮之后,你以同样的方式重复算法。
A + 1 C + 1 ...
例如,我有一个支架 这有8个条目(A,B,C,D,E,F,G,H)
您应该能够弄清楚如何解析它。这似乎是一个家庭作业问题。
答案 4 :(得分:0)
考虑重新编号游戏(之后您可以随时重新编号)
如果决赛是1 半决赛是2,3 这个问题已经得到了很好的解决方案:ahnentafel(德语为祖先表)已经被系谱学家使用了很长时间 - http://en.wikipedia.org/wiki/Ahnentafel
其中一个有趣的部分是游戏的二进制表示法#给出了很多关于锦标赛结构以及比赛所在树的位置的信息。
同时请注意,因为每场比赛都会淘汰1名参赛者,对于n个参赛者,将会有n-1场比赛