我必须比较不应将单个项目与其自身进行比较的M
个项目。在这种情况下,我想设计一个算法来查找nth
比较。例如,如果我正在比较2个项目,则比较列表应为:
2: (1,2)
同样,如果我比较3个项目,那么比较列表应为:
3: (1,2), (1,3), (2,3)
遵循这种模式:
4: (1,2), (1,3), (1,4), (2,3), (2,4), (3,4)
5: (1,2), (1,3), (1,4), (1,5), (2,3), (2,4), (2,5), (3,4), (3,5), (4,5)
等等。
我的问题是,如果输入为nth
,(i,j)
项M
是什么?
M: (1,2), ..., (i,j), ..., (M-1,M)
虽然我可以轻松编写一个简单的程序来计算这个特设,但我想知道是否有一个封闭的表单解决方案,以便它不会与M
一起扩展。
编辑:为了使这个更清晰(并且有一个可以用于测试的示例),我希望代码位于C
中,并带有以下模板:
void findIJ(int M, int n) {
int i = 0;
int j = 0;
/* Do work to find i and j*/
printf("(i,j) = (%i,%i)\n", i, j);
}
答案 0 :(得分:0)
第n个是(i,j):
i = max(k; Sum(M-i, i = 1, k) <= n)
i = max(k; M*k - k*(k+1)/2 <= n)
i = 1 + floor(1/2*(-1+2*M-sqrt(1-4*M+4*M*M-8*(n-1))))
所以:
j = n - M * (i-1) + i*(i+1)/2
答案 1 :(得分:0)
private static void nth(int m, int n) {
int counter = 1;
for (int i = 1; i < m; i++) {
for (int j = i + 1; j <= m; j++) {
if (counter == n) {
System.out.println(i + " " + j);
return;
}
counter++;
}
}
}
答案 2 :(得分:0)
如果序列1, 2, 2, 3, 3, 3, 4, 4, 4, 4
有多少个小于或等于4的数字?其中1+2+3+4
= 10
。 1+2+...+n = n*(n+1)/2
的公式。现在另一方面,位置x=10
上的数字是多少,从1开始计算位置? x = n*(n+1)/2
,这是二次方程和n = (sqrt(1+8*x)-1)/2
。对于x = 10,它是4.位置7上的数字是多少?该公式给出了类似3.275的结果...事实证明,我们所需要的只是将它四舍五入,然后我们再次得到4。
与原始问题的连接很接近。如果我们从5中减去序列,我们得到4, 3, 3, 2, 2, 2, 1, 1, 1, 1
,如果我们反过来,我们得到1, 1, 1, 1, 2, 2, 2, 3, 3, 4
。这是我们的第一对数。第二个数字可以从公式给出整数的位置到距离来计算,实际上比解释更容易实现。代码是C#,应该很容易适应C。
int sqrSum(int n)
{
return n * (n + 1) / 2;
}
void GetNth(int M, int n)
{
int total = sqrSum(M - 1);
int nReversed = total + 1 - n;
int closestBigger = (int)Math.Ceiling((Math.Sqrt(1 + 8 * nReversed) - 1) / 2);
int difference = sqrSum(closestBigger) - nReversed;
int i = M - closestBigger;
int j = i + 1 + difference;
textBox2.AppendText("(" + i + ", " + j + "), " + Environment.NewLine);
}
代码依赖于事实,即sqrt是准确的。根据IEEE应该是,但事实并非如此,必须将sqrt作为估计值,并且必须在整数范围内验证上限。