2012-07-05 19 views
5

,所以我有一个排名系统,基本上是一个金字塔:如何获得在金字塔的排名系统的挑战者

 01 
    02 03 
    04 05 06 
    07 08 09 10 
11 12 13 14 15 
16 17 18 19 20 21 

现在,每个人都可以每个人的挑战,在同一行中,并在右侧的左上面一排。

因此,例如18可以challange 13-17
基本上,你可以进一步挑战更低的阶梯。

关于如何解决这个函数的任何想法?当想到这个问题时,我只需通过倒数计算金字塔层来计算范围的一些相当复杂的计算,但我相信必须有一个简单的解决方案。

的范围内一些更exmaples:
02 - 01
03 - 02
04 - 02 - 03
05 - 03 - 04
06 - 04 - 05
07 - 04-06
08 - 05 - 07
11 - 07 - 10
17 - 12-16

顺便说一下,即使它可能看起来像功课,我可以向你保证我已经出几年来的学校。这实际上是进入射箭梯系统,我试图数字化本地射箭俱乐部:)

回答

9

对于球员x不难看出,在范围上限值始终x - 1。棘手的部分是找到较低的值。

首先请注意,您可以挑战的人数等于您上面一排中的人数。您可能会发现更容易理解为什么这是真的通过查看下图中,每个椭圆形包含完全相同的人的一个球员13可以挑战(9,10,11,12):

showing relationship to triangular numbers

有四个人是13号可以挑战,以及四人行中的上述球员13


所以我们需要找到上述X行中的人数。请注意,对于某些n,以上x的总人数为triangular numberT(n)n的值是x上面一行中的人数。

要找到三角号码你会发现这个公式有用:

T(n) = n * (n+1)/2 

的问题是要找到最大的n这样T(n) < x

您可以使用循环遍历所有可能的值n,计算T(n),直到它超过x。这会起作用,这很简单,而且对于你的目的来说,它几乎肯定会足够快。

但是你也可以通过使用inverse of the above quadratic equation那里更直接:

inverse of triangulare number formula

所需要的是首先从x减去1,因为我们想要的三角形数量严格大于x较小的唯一调整。没有这种调整,它会给出当前行为准确的三角形数字,而不是上面的行。

使用这个公式,将其转换成PHP中,我们可以直接得到的结果对于任何x

$n = floor((sqrt(1 + 8 * ($x - 1)) - 1)/2); 
$lower = $x - $n; 
$upper = $x - 1; 

结果:

 
2: 1 - 1 
3: 2 - 2 
4: 2 - 3 
5: 3 - 4 
6: 4 - 5 
7: 4 - 6 
8: 5 - 7 
9: 6 - 8 
10: 7 - 9 
11: 7 - 10 
12: 8 - 11 
13: 9 - 12 
14: 10 - 13 
15: 11 - 14 
16: 11 - 15 
17: 12 - 16 
18: 13 - 17 
19: 14 - 18 
20: 15 - 19 
21: 16 - 20 

看到它联机工作:ideone

+0

FWIW,这些方程源自树遍历算法。 – 2012-07-05 21:04:45

+0

我不是百分之百肯定,如果我明白为什么,但它的工作,谢谢:D – bardiir 2012-07-05 21:11:09

+0

@bardiir:我已经发布了一些更多的解释。这有助于你理解它为什么起作用吗? – 2012-07-05 21:55:23