通过增加整数对的渐进循环

时间:2012-06-23 20:39:28

标签: arrays

假设有人想要搜索满足某个方程的整数x和y a对,例如(在我的头顶上)7 x ^ 2 + x y - 3 y ^ 2 = 5

(我知道有很有效的方法可以找到像这样的二次方的整数解;但这与本问题的目的无关。)

显而易见的方法是使用一个简单的双循环“for x = -max to max; for y = -max to max {blah}”但是为了让搜索停止并恢复,更方便的方法,想象一下x和y作为平面中点的正方形点阵的可能整数,是从原点向外围绕“方形螺旋”,在(比如说)右上角开始和停止。

所以基本上,我要求一个简单而合理的“伪代码”,让循环分别在点(m,m)和(n,n)处开始和停止这个过程。

对于额外的荣誉,如果读者倾向于我,我建议如果x中的一个可以被认为是非负的,或者如果两个都可以被认为是非负的,那么也提供循环。这可能有点容易,特别是第二次。

我可以毫不费力地把自己放在自己身上,但我很想看到其他人的想法。

对于那些喜欢用白板折磨候选人的可怕面试官来说,这会带来相当好的“建设性”面试挑战; - )

2 个答案:

答案 0 :(得分:0)

def enumerateIntegerPairs(fromRadius, toRadius):
    for radius in range(fromRadius, toRadius + 1):
        if radius == 0: yield (0, 0)
        for x in range(-radius, radius): yield (x, radius)
        for y in range(-radius, radius): yield (radius, -y)
        for x in range(-radius, radius): yield (-x, -radius)
        for y in range(-radius, radius): yield (-radius, y)

答案 1 :(得分:0)

这是一个简单的实现(也在ideone上):

void turn(int *dr, int *dc) {
    int tmp = *dc;
    *dc = -*dr;
    *dr = tmp;
}
int main(void) {
    int N = 3;
    int r = 0, c = 0;
    int sz = 0;
    int dr = 1, dc = 0, cnt = 0;
    while (r != N+1 && c != N+1) {
        printf("%d %d\n", r, c);
        if (cnt == sz) {
            turn(&dr, &dc);
            cnt = 0;
            if (dr == 0 && dc == -1) {
                r++;
                c++;
                sz += 2;
            }
        }
        cnt++;
        r += dr;
        c += dc;
    }
    return 0;
}

实现中的关键是turn函数,它在给出一对{delta-Row, delta-Col}的情况下执行右转。其余的是直截了当的算术。