2012-07-05 51 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