到目前为止,我在这里看到的两个答案都可以很好地进行第一个计算,但是向后计算需要循环,这是不必要的。
考虑以下带有的示例
n=5,该示例显示了元素的编号方式。
0 1 2 3 4 +---+---+---+---+---+0 | | | | | | +---+---+---+---+---+1 | 0 | | | | | +---+---+---+---+---+2 | 1 | 4 | | | | +---+---+---+---+---+3 | 2 | 5 | 7 | | | +---+---+---+---+---+4 | 3 | 6 | 8 | 9 | | +---+---+---+---+---+
给定一个元组
(x, y)(假设
x < y),列中的第一个索引
x由下式给出
n-1 + n-2 + ... + n-x = (n-1 + n-x) * x / 2 = (2n - x - 1) * x / 2
该列中的偏移量仅为
y - x - 1。这产生了总表达
p_n(x, y) = (2n - x - 1) * x / 2 + y-x-1 = (2n - x - 3) * x / 2 + y-1
现在,走另一条路很棘手。我们有一些价值观
p,
n需要找到
x和
y。尽管可以通过假设正在寻找列中的第一个单元格来使生活变得更简单
y =x+1。如果将其插入上面的公式中,我们将获得
p = (2n - x - 1) * x / 2
重写此公式将得出
x^2 - (2n-1) * x + 2p = 0
这是一个简单的二次方程,可以求解x:
x = [(2n-1) - Sqrt((2n-1)^2 - 8p)] / 2
当然,我们可能高估了
x,因为我们假设的可能值最低
y。但是,我们相差不远(仍在右列中),因此舍入该值就足以得到real
x。
将
x我们发现的值代入原始公式中,得出以下公式非常简单
y:
x = Floor( [(2n-1) - Sqrt((2n-1)^2 - 8p)] / 2 )y = p - (2n - x - 3) * x / 2 + 1
可以说,对数字取平方根是很慢的操作(这是正确的),但是对于较大的值,此方法将胜过循环
n。



