两数的平方和
Edsger Dijkstra 在他1976出版的书 The Discipline of Programming 中提出了这样一个问题:写一个函数,对于指定的n,找到所有的x和y,且 x ≥ y ≥ 0,使得 x² + y² = n;比如说,50 = 7² + 1² = 5² + 5², 48612265 = 6972² + 59² = 6971² + 132² = ……,而999没有这样的数。
Dijkstra 提出的方法可以在在一次扫描中找到所有的数,x从n的平方根开始扫描,y从0开始扫描,假设函数 B(x, y) 可以返回x和y之间所有合适的数,使用下面的规则来进行递归:
- 如果 x² + y² < n,那么 B(x, y) = B(x, y+1),因为x总是变小,只有y变大才能得到结果。
- 如果 x² + y² = n,那么 (x, y) 就是答案,B(x, y) = B(x-1, y+1),扫描继续。
- 如果 x² + y² > n,那么 B(x, y) = B(x-1, y),因为y总是在变大。
- 最后,如果 x < y,递归结束。
上面的描述可以归纳成下面的函数: