5

所以我得到了一个基本上是金字塔的排名系统:

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

现在每个人都可以挑战同一排左边的每个人和上排右边的每个人。

因此,例如 18 可以挑战 13-17
基本上您可以在阶梯上挑战越低的位置。

关于如何解决这个问题的任何想法?在考虑这个问题时,我只是通过倒计时计算金字塔的层数来计算范围的一些非常复杂的计算,但我确信必须有一个简单的解决方案。

范围的更多示例:
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

顺便说一句,即使它看起来像家庭作业,我可以向你保证我已经离开学校好几年了。这实际上是进入我正在尝试为当地射箭俱乐部数字化的射箭梯系统:)

4

1 回答 1

9

对于玩家x来说,很容易看出该范围内的上限值始终为x - 1。棘手的部分是找到较低的值。

首先请注意,您可以挑战的人数等于您上方一排的人数。通过查看下图,您可能会更容易理解为什么这是真的,其中每个椭圆恰好包含玩家 13 可以挑战的人之一(9、10、11、12):

显示与三角数的关系

13号可以挑战的人有4个人,13号玩家上方的那一排有4个人。


所以我们需要找到 x 上面那一行的人数。请注意,x 以上的总人数是some的三角形数 。的值是 x 上方行中的人数。T(n)nn

要查找三角数,您可能会发现此公式很有用:

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

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

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

但是您也可以通过使用上述二次方程的逆来更直接地到达那里:

倒三角数公式

唯一需要的调整是首先减去1x因为我们希望三角形数严格小于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

于 2012-07-05T21:00:33.633 回答