有趣的问题,如果您只能逐行遍历数组。我将矩形分为三个区域。左上角三角形,右下角三角形和中间的菱形。
对于左上角的三角形,第一列(x=0)中的值可以使用常见算术级数1 + 2 + 3 + .. + n = n *(n + 1)/ 2进行计算。具有相同x+y值的该三角形中的字段在同一对角线上,它们的值是来自第一列+x的总和。
相同的方法适用于右下角的三角形。但是,使用w-x和h-y而不是x和y,其中w是矩形的宽度,h是高度。该值必须从数组中最高值w*h-1中减去。
对于中间的菱形,有两种情况。如果矩形的宽度大于(或等于)高度,则矩形的左下角字段是菱形中最低值的字段,并且可以通过h-1之前的总和进行计算。从那里开始,您可以想象菱形是一个矩形,其x值为x+y,原始矩形的y值为y。因此,计算该新矩形中剩余值很容易。在另一种情况下,当高度大于宽度时,可以使用该算术总和计算位于x=w-1和y=0的字段,并且可以将菱形想象为x值为x,y值为y-(w-x-1)的矩形。
代码可以通过预先计算值进行优化。我认为还有一个适用于所有情况的公式。也许我以后会考虑它。
inline static int diagonalvalue(int x, int y, int w, int h) {
if (h > x+y+1 && w > x+y+1) {
return ((x+y)*(x+y+1)/2) + x;
} else if (y+x >= h && y+x >= w) {
return w*h - (((w-x-1)+(h-y-1))*((w-x-1)+(h-y-1)+1)/2) - (w-x-1) - 1;
}
if (w >= h) {
return (h*(h+1)/2) + ((x+y+1)-h)*h - y - 1;
}
return (w*(w+1)/2) + ((x+y)-w)*w + x;
}
for (y=0; y<h; y++) {
for (x=0; x<w; x++) {
array[x][y] = diagonalvalue(x,y,w,h);
}
}
当然,如果没有这样的限制,类似这样的东西应该会更快:
n = w*h;
x = 0;
y = 0;
for (i=0; i<n; i++) {
array[x][y] = i;
if (y <= 0 || x+1 >= w) {
y = x+y+1;
if (y >= h) {
x = (y-h)+1;
y -= x;
} else {
x = 0;
}
} else {
x++;
y--;
}
}
array[x][y]
即可直接找到f(x,y)... - BlueRaja - Danny Pflughoeft